localed.c revision 6203e07a83214a55bb1f88508fcda2005c601dea
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek/***
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek This file is part of systemd.
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek Copyright 2011 Lennart Poettering
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek Copyright 2013 Kay Sievers
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek systemd is free software; you can redistribute it and/or modify it
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek under the terms of the GNU Lesser General Public License as published by
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek the Free Software Foundation; either version 2.1 of the License, or
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek (at your option) any later version.
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek systemd is distributed in the hope that it will be useful, but
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek WITHOUT ANY WARRANTY; without even the implied warranty of
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek Lesser General Public License for more details.
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek You should have received a copy of the GNU Lesser General Public License
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek along with systemd; If not, see <http://www.gnu.org/licenses/>.
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek***/
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek#include <errno.h>
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek#include <string.h>
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek#include <unistd.h>
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek#include "sd-bus.h"
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek#include "util.h"
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek#include "mkdir.h"
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek#include "strv.h"
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek#include "def.h"
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmek#include "env-util.h"
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek#include "fileio.h"
2cf4172a71860c6e44edd27a3b68047ae062d7fcLennart Poettering#include "fileio-label.h"
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek#include "label.h"
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek#include "bus-util.h"
799a8f39d8eb9ea725e85a598c0f5dbd658c8ba7Zbigniew Jędrzejewski-Szmek#include "bus-error.h"
799a8f39d8eb9ea725e85a598c0f5dbd658c8ba7Zbigniew Jędrzejewski-Szmek#include "bus-message.h"
799a8f39d8eb9ea725e85a598c0f5dbd658c8ba7Zbigniew Jędrzejewski-Szmek#include "event-util.h"
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmekenum {
2cf4172a71860c6e44edd27a3b68047ae062d7fcLennart Poettering /* We don't list LC_ALL here on purpose. People should be
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek * using LANG instead. */
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek LOCALE_LANG,
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek LOCALE_LANGUAGE,
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek LOCALE_LC_CTYPE,
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek LOCALE_LC_NUMERIC,
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek LOCALE_LC_TIME,
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek LOCALE_LC_COLLATE,
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek LOCALE_LC_MONETARY,
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek LOCALE_LC_MESSAGES,
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek LOCALE_LC_PAPER,
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek LOCALE_LC_NAME,
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek LOCALE_LC_ADDRESS,
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek LOCALE_LC_TELEPHONE,
2cf4172a71860c6e44edd27a3b68047ae062d7fcLennart Poettering LOCALE_LC_MEASUREMENT,
2cf4172a71860c6e44edd27a3b68047ae062d7fcLennart Poettering LOCALE_LC_IDENTIFICATION,
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek _LOCALE_MAX
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek};
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmekstatic const char * const names[_LOCALE_MAX] = {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek [LOCALE_LANG] = "LANG",
8847551bcbfa8265bae04f567bb1aadc7b480325Zbigniew Jędrzejewski-Szmek [LOCALE_LANGUAGE] = "LANGUAGE",
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek [LOCALE_LC_CTYPE] = "LC_CTYPE",
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek [LOCALE_LC_NUMERIC] = "LC_NUMERIC",
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek [LOCALE_LC_TIME] = "LC_TIME",
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek [LOCALE_LC_COLLATE] = "LC_COLLATE",
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek [LOCALE_LC_MONETARY] = "LC_MONETARY",
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek [LOCALE_LC_MESSAGES] = "LC_MESSAGES",
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek [LOCALE_LC_PAPER] = "LC_PAPER",
8847551bcbfa8265bae04f567bb1aadc7b480325Zbigniew Jędrzejewski-Szmek [LOCALE_LC_NAME] = "LC_NAME",
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek [LOCALE_LC_ADDRESS] = "LC_ADDRESS",
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek [LOCALE_LC_TELEPHONE] = "LC_TELEPHONE",
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek [LOCALE_LC_MEASUREMENT] = "LC_MEASUREMENT",
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek [LOCALE_LC_IDENTIFICATION] = "LC_IDENTIFICATION"
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek};
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmektypedef struct Context {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek char *locale[_LOCALE_MAX];
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek char *x11_layout;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek char *x11_model;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek char *x11_variant;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek char *x11_options;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek char *vc_keymap;
c33b329709ebe2755181980a050d02ec7c81ed87Michal Schmidt char *vc_keymap_toggle;
c33b329709ebe2755181980a050d02ec7c81ed87Michal Schmidt
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek Hashmap *polkit_registry;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek} Context;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekstatic int free_and_copy(char **s, const char *v) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek int r;
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmek char *t;
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmek
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmek assert(s);
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmek
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmek r = strdup_or_null(isempty(v) ? NULL : v, &t);
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmek if (r < 0)
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmek return r;
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmek
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmek free(*s);
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt *s = t;
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt return 0;
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmek}
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmek
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidtstatic void free_and_replace(char **s, char *v) {
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt free(*s);
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt *s = v;
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmek}
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmek
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmekstatic void context_free_x11(Context *c) {
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmek free_and_replace(&c->x11_layout, NULL);
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmek free_and_replace(&c->x11_model, NULL);
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek free_and_replace(&c->x11_variant, NULL);
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek free_and_replace(&c->x11_options, NULL);
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek}
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmekstatic void context_free_vconsole(Context *c) {
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek free_and_replace(&c->vc_keymap, NULL);
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek free_and_replace(&c->vc_keymap_toggle, NULL);
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek}
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmekstatic void context_free_locale(Context *c) {
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek int p;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek for (p = 0; p < _LOCALE_MAX; p++)
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek free_and_replace(&c->locale[p], NULL);
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek}
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmekstatic void context_free(Context *c, sd_bus *bus) {
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek context_free_locale(c);
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek context_free_x11(c);
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek context_free_vconsole(c);
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek bus_verify_polkit_async_registry_free(bus, c->polkit_registry);
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek};
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmekstatic void locale_simplify(Context *c) {
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek int p;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt for (p = LOCALE_LANG+1; p < _LOCALE_MAX; p++)
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek if (isempty(c->locale[p]) || streq_ptr(c->locale[LOCALE_LANG], c->locale[p])) {
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek free(c->locale[p]);
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek c->locale[p] = NULL;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek }
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek}
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmekstatic int locale_read_data(Context *c) {
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek int r;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek context_free_locale(c);
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek r = parse_env_file("/etc/locale.conf", NEWLINE,
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek "LANG", &c->locale[LOCALE_LANG],
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek "LANGUAGE", &c->locale[LOCALE_LANGUAGE],
36d4739a68c3edafe4d145d525a26de4ef0b8e5aZbigniew Jędrzejewski-Szmek "LC_CTYPE", &c->locale[LOCALE_LC_CTYPE],
36d4739a68c3edafe4d145d525a26de4ef0b8e5aZbigniew Jędrzejewski-Szmek "LC_NUMERIC", &c->locale[LOCALE_LC_NUMERIC],
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt "LC_TIME", &c->locale[LOCALE_LC_TIME],
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt "LC_COLLATE", &c->locale[LOCALE_LC_COLLATE],
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt "LC_MONETARY", &c->locale[LOCALE_LC_MONETARY],
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt "LC_MESSAGES", &c->locale[LOCALE_LC_MESSAGES],
36d4739a68c3edafe4d145d525a26de4ef0b8e5aZbigniew Jędrzejewski-Szmek "LC_PAPER", &c->locale[LOCALE_LC_PAPER],
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek "LC_NAME", &c->locale[LOCALE_LC_NAME],
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek "LC_ADDRESS", &c->locale[LOCALE_LC_ADDRESS],
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek "LC_TELEPHONE", &c->locale[LOCALE_LC_TELEPHONE],
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek "LC_MEASUREMENT", &c->locale[LOCALE_LC_MEASUREMENT],
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek "LC_IDENTIFICATION", &c->locale[LOCALE_LC_IDENTIFICATION],
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek NULL);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (r == -ENOENT) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek int p;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek /* Fill in what we got passed from systemd. */
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek for (p = 0; p < _LOCALE_MAX; p++) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek assert(names[p]);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = free_and_copy(&c->locale[p], getenv(names[p]));
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (r < 0)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return r;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek }
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = 0;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek }
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek locale_simplify(c);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return r;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek}
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic int vconsole_read_data(Context *c) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek int r;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek context_free_vconsole(c);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = parse_env_file("/etc/vconsole.conf", NEWLINE,
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek "KEYMAP", &c->vc_keymap,
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek "KEYMAP_TOGGLE", &c->vc_keymap_toggle,
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek NULL);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (r < 0 && r != -ENOENT)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return r;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return 0;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek}
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic int x11_read_data(Context *c) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek FILE *f;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek char line[LINE_MAX];
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek bool in_section = false;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek context_free_x11(c);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek f = fopen("/etc/X11/xorg.conf.d/00-keyboard.conf", "re");
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (!f)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return errno == ENOENT ? 0 : -errno;
b88a40a7e592e0a4a2e6e8eb1ed3721989ba5d0ePhilippe De Swert
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek while (fgets(line, sizeof(line), f)) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek char *l;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek char_array_0(line);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek l = strstrip(line);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (l[0] == 0 || l[0] == '#')
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek continue;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (in_section && first_word(l, "Option")) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek char **a;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek a = strv_split_quoted(l);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (!a) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek fclose(f);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return -ENOMEM;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek }
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (strv_length(a) == 3) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (streq(a[1], "XkbLayout")) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek free_and_replace(&c->x11_layout, a[2]);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek a[2] = NULL;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek } else if (streq(a[1], "XkbModel")) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek free_and_replace(&c->x11_model, a[2]);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek a[2] = NULL;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek } else if (streq(a[1], "XkbVariant")) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek free_and_replace(&c->x11_variant, a[2]);
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek a[2] = NULL;
799a8f39d8eb9ea725e85a598c0f5dbd658c8ba7Zbigniew Jędrzejewski-Szmek } else if (streq(a[1], "XkbOptions")) {
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek free_and_replace(&c->x11_options, a[2]);
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek a[2] = NULL;
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek }
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek }
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek
8847551bcbfa8265bae04f567bb1aadc7b480325Zbigniew Jędrzejewski-Szmek strv_free(a);
8847551bcbfa8265bae04f567bb1aadc7b480325Zbigniew Jędrzejewski-Szmek
8847551bcbfa8265bae04f567bb1aadc7b480325Zbigniew Jędrzejewski-Szmek } else if (!in_section && first_word(l, "Section")) {
8847551bcbfa8265bae04f567bb1aadc7b480325Zbigniew Jędrzejewski-Szmek char **a;
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek a = strv_split_quoted(l);
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek if (!a) {
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek fclose(f);
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek return -ENOMEM;
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek }
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (strv_length(a) == 2 && streq(a[1], "InputClass"))
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek in_section = true;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek strv_free(a);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek } else if (in_section && first_word(l, "EndSection"))
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek in_section = false;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek fclose(f);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return 0;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek}
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic int context_read_data(Context *c) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek int r, q, p;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = locale_read_data(c);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek q = vconsole_read_data(c);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek p = x11_read_data(c);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return r < 0 ? r : q < 0 ? q : p;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek}
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic int locale_write_data(Context *c) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek int r, p;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek char **l = NULL;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = load_env_file("/etc/locale.conf", NULL, &l);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (r < 0 && r != -ENOENT)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return r;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek for (p = 0; p < _LOCALE_MAX; p++) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek char *t, **u;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek assert(names[p]);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (isempty(c->locale[p])) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek l = strv_env_unset(l, names[p]);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek continue;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek }
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (asprintf(&t, "%s=%s", names[p], c->locale[p]) < 0) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek strv_free(l);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return -ENOMEM;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek }
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek u = strv_env_set(l, t);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek free(t);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek strv_free(l);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (!u)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return -ENOMEM;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek l = u;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek }
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (strv_isempty(l)) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek strv_free(l);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (unlink("/etc/locale.conf") < 0)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return errno == ENOENT ? 0 : -errno;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return 0;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek }
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = write_env_file_label("/etc/locale.conf", l);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek strv_free(l);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
8201af08fa09c2bd0f005fbe262f27e2c5bd2d86Zbigniew Jędrzejewski-Szmek return r;
8201af08fa09c2bd0f005fbe262f27e2c5bd2d86Zbigniew Jędrzejewski-Szmek}
8201af08fa09c2bd0f005fbe262f27e2c5bd2d86Zbigniew Jędrzejewski-Szmek
8201af08fa09c2bd0f005fbe262f27e2c5bd2d86Zbigniew Jędrzejewski-Szmekstatic int locale_update_system_manager(Context *c, sd_bus *bus) {
8201af08fa09c2bd0f005fbe262f27e2c5bd2d86Zbigniew Jędrzejewski-Szmek _cleanup_free_ char **l_unset = NULL;
8201af08fa09c2bd0f005fbe262f27e2c5bd2d86Zbigniew Jędrzejewski-Szmek _cleanup_strv_free_ char **l_set = NULL;
8201af08fa09c2bd0f005fbe262f27e2c5bd2d86Zbigniew Jędrzejewski-Szmek _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
8201af08fa09c2bd0f005fbe262f27e2c5bd2d86Zbigniew Jędrzejewski-Szmek sd_bus_error error = SD_BUS_ERROR_NULL;
8201af08fa09c2bd0f005fbe262f27e2c5bd2d86Zbigniew Jędrzejewski-Szmek unsigned c_set, c_unset, p;
8201af08fa09c2bd0f005fbe262f27e2c5bd2d86Zbigniew Jędrzejewski-Szmek int r;
8201af08fa09c2bd0f005fbe262f27e2c5bd2d86Zbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek assert(bus);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek l_unset = new0(char*, _LOCALE_MAX);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (!l_unset)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return -ENOMEM;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek l_set = new0(char*, _LOCALE_MAX);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (!l_set)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return -ENOMEM;
e1ad6e245dcf63faa8f183063eb97678f4f9ac94Lukas Nykryn
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek for (p = 0, c_set = 0, c_unset = 0; p < _LOCALE_MAX; p++) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek assert(names[p]);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (isempty(c->locale[p]))
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek l_unset[c_set++] = (char*) names[p];
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt else {
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt char *s;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (asprintf(&s, "%s=%s", names[p], c->locale[p]) < 0)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return -ENOMEM;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek l_set[c_unset++] = s;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt assert(c_set + c_unset == _LOCALE_MAX);
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt r = sd_bus_message_new_method_call(bus,
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek "org.freedesktop.systemd1",
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek "/org/freedesktop/systemd1",
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek "org.freedesktop.systemd1.Manager",
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek "UnsetAndSetEnvironment", &m);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (r < 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return r;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = sd_bus_message_append_strv(m, l_unset);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (r < 0)
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek return r;
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek r = sd_bus_message_append_strv(m, l_set);
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek if (r < 0)
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek return r;
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek r = sd_bus_call(bus, m, 0, &error, NULL);
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek if (r < 0)
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek log_error("Failed to update the manager environment: %s", strerror(-r));
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek return 0;
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek}
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmekstatic int vconsole_write_data(Context *c) {
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek int r;
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek _cleanup_strv_free_ char **l = NULL;
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek r = load_env_file("/etc/vconsole.conf", NULL, &l);
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek if (r < 0 && r != -ENOENT)
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek return r;
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek if (isempty(c->vc_keymap))
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek l = strv_env_unset(l, "KEYMAP");
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek else {
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek char *s, **u;
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek s = strappend("KEYMAP=", c->vc_keymap);
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek if (!s)
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek return -ENOMEM;
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek u = strv_env_set(l, s);
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek free(s);
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek strv_free(l);
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek if (!u)
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek return -ENOMEM;
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek l = u;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek }
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (isempty(c->vc_keymap_toggle))
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek l = strv_env_unset(l, "KEYMAP_TOGGLE");
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek else {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek char *s, **u;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek s = strappend("KEYMAP_TOGGLE=", c->vc_keymap_toggle);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (!s)
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek return -ENOMEM;
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek u = strv_env_set(l, s);
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek free(s);
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek strv_free(l);
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek if (!u)
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek return -ENOMEM;
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek l = u;
5bc891206dd8eb4e4df58f502b0184b8426caf22Zbigniew Jędrzejewski-Szmek }
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek if (strv_isempty(l)) {
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek if (unlink("/etc/vconsole.conf") < 0)
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek return errno == ENOENT ? 0 : -errno;
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek return 0;
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek }
5bc891206dd8eb4e4df58f502b0184b8426caf22Zbigniew Jędrzejewski-Szmek
5bc891206dd8eb4e4df58f502b0184b8426caf22Zbigniew Jędrzejewski-Szmek r = write_env_file_label("/etc/vconsole.conf", l);
5bc891206dd8eb4e4df58f502b0184b8426caf22Zbigniew Jędrzejewski-Szmek return r;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek}
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic int write_data_x11(Context *c) {
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt _cleanup_fclose_ FILE *f = NULL;
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt _cleanup_free_ char *temp_path = NULL;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek int r;
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt if (isempty(c->x11_layout) &&
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt isempty(c->x11_model) &&
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek isempty(c->x11_variant) &&
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek isempty(c->x11_options)) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (unlink("/etc/X11/xorg.conf.d/00-keyboard.conf") < 0)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return errno == ENOENT ? 0 : -errno;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return 0;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek }
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek mkdir_p_label("/etc/X11/xorg.conf.d", 0755);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek r = fopen_temporary("/etc/X11/xorg.conf.d/00-keyboard.conf", &f, &temp_path);
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek if (r < 0)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return r;
5bc891206dd8eb4e4df58f502b0184b8426caf22Zbigniew Jędrzejewski-Szmek
5bc891206dd8eb4e4df58f502b0184b8426caf22Zbigniew Jędrzejewski-Szmek fchmod(fileno(f), 0644);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek fputs("# Read and parsed by systemd-localed. It's probably wise not to edit this file\n"
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek "# manually too freely.\n"
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek "Section \"InputClass\"\n"
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " Identifier \"system-keyboard\"\n"
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek " MatchIsKeyboard \"on\"\n", f);
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (!isempty(c->x11_layout))
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek fprintf(f, " Option \"XkbLayout\" \"%s\"\n", c->x11_layout);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (!isempty(c->x11_model))
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek fprintf(f, " Option \"XkbModel\" \"%s\"\n", c->x11_model);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (!isempty(c->x11_variant))
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek fprintf(f, " Option \"XkbVariant\" \"%s\"\n", c->x11_variant);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (!isempty(c->x11_options))
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek fprintf(f, " Option \"XkbOptions\" \"%s\"\n", c->x11_options);
30776485c5bc2d9c356e875f2aee874d22c393b7Zbigniew Jędrzejewski-Szmek
30776485c5bc2d9c356e875f2aee874d22c393b7Zbigniew Jędrzejewski-Szmek fputs("EndSection\n", f);
30776485c5bc2d9c356e875f2aee874d22c393b7Zbigniew Jędrzejewski-Szmek fflush(f);
30776485c5bc2d9c356e875f2aee874d22c393b7Zbigniew Jędrzejewski-Szmek
30776485c5bc2d9c356e875f2aee874d22c393b7Zbigniew Jędrzejewski-Szmek if (ferror(f) || rename(temp_path, "/etc/X11/xorg.conf.d/00-keyboard.conf") < 0) {
30776485c5bc2d9c356e875f2aee874d22c393b7Zbigniew Jędrzejewski-Szmek r = -errno;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek unlink("/etc/X11/xorg.conf.d/00-keyboard.conf");
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek unlink(temp_path);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek } else
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return 0;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek}
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekstatic int vconsole_reload(sd_bus *bus) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek int r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek assert(bus);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek r = sd_bus_call_method(bus,
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek "org.freedesktop.systemd1",
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek "/org/freedesktop/systemd1",
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek "org.freedesktop.systemd1.Manager",
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek "RestartUnit",
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek &error,
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek NULL,
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek "ss", "systemd-vconsole-setup.service", "replace");
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek if (r < 0)
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek return r;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek}
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekstatic char *strnulldash(const char *s) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return s == NULL || *s == 0 || (s[0] == '-' && s[1] == 0) ? NULL : (char*) s;
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek}
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmekstatic int read_next_mapping(FILE *f, unsigned *n, char ***a) {
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek assert(f);
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek assert(n);
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek assert(a);
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek for (;;) {
bf257aed057efd113f1b84e037fde09ffeed32eeJosh Triplett char line[LINE_MAX];
bf257aed057efd113f1b84e037fde09ffeed32eeJosh Triplett char *l, **b;
bf257aed057efd113f1b84e037fde09ffeed32eeJosh Triplett
bf257aed057efd113f1b84e037fde09ffeed32eeJosh Triplett errno = 0;
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek if (!fgets(line, sizeof(line), f)) {
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (ferror(f))
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return errno ? -errno : -EIO;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering return 0;
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering }
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek
50a0b0717563d08c027a16a896bff8d7754eab9eZbigniew Jędrzejewski-Szmek (*n) ++;
1af719edc5958c01c19204fb68d6fc45c9eea85cZbigniew Jędrzejewski-Szmek
1af719edc5958c01c19204fb68d6fc45c9eea85cZbigniew Jędrzejewski-Szmek l = strstrip(line);
1af719edc5958c01c19204fb68d6fc45c9eea85cZbigniew Jędrzejewski-Szmek if (l[0] == 0 || l[0] == '#')
1af719edc5958c01c19204fb68d6fc45c9eea85cZbigniew Jędrzejewski-Szmek continue;
1af719edc5958c01c19204fb68d6fc45c9eea85cZbigniew Jędrzejewski-Szmek
1af719edc5958c01c19204fb68d6fc45c9eea85cZbigniew Jędrzejewski-Szmek b = strv_split_quoted(l);
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering if (!b)
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering return -ENOMEM;
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering if (strv_length(b) < 5) {
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering log_error("Invalid line "SYSTEMD_KBD_MODEL_MAP":%u, ignoring.", *n);
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering strv_free(b);
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering continue;
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering }
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering *a = b;
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering return 1;
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering }
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek}
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic int vconsole_convert_to_x11(Context *c, sd_bus *bus) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek bool modified = false;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek assert(bus);
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek if (isempty(c->vc_keymap)) {
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek modified =
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek !isempty(c->x11_layout) ||
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek !isempty(c->x11_model) ||
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek !isempty(c->x11_variant) ||
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek !isempty(c->x11_options);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek context_free_x11(c);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek } else {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek _cleanup_fclose_ FILE *f = NULL;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek unsigned n = 0;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek f = fopen(SYSTEMD_KBD_MODEL_MAP, "re");
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (!f)
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek return -errno;
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek for (;;) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek _cleanup_strv_free_ char **a = NULL;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek int r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek r = read_next_mapping(f, &n, &a);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (r < 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (r == 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek break;
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek if (!streq(c->vc_keymap, a[0]))
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek continue;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (!streq_ptr(c->x11_layout, strnulldash(a[1])) ||
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek !streq_ptr(c->x11_model, strnulldash(a[2])) ||
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek !streq_ptr(c->x11_variant, strnulldash(a[3])) ||
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek !streq_ptr(c->x11_options, strnulldash(a[4]))) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (free_and_copy(&c->x11_layout, strnulldash(a[1])) < 0 ||
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek free_and_copy(&c->x11_model, strnulldash(a[2])) < 0 ||
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek free_and_copy(&c->x11_variant, strnulldash(a[3])) < 0 ||
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek free_and_copy(&c->x11_options, strnulldash(a[4])) < 0)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return -ENOMEM;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek modified = true;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek }
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek break;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek }
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek }
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (modified) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek int r;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = write_data_x11(c);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (r < 0)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek log_error("Failed to set X11 keyboard layout: %s", strerror(-r));
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek sd_bus_emit_properties_changed(bus,
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek "/org/freedesktop/locale1",
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek "org.freedesktop.locale1",
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek "X11Layout", "X11Model", "X11Variant", "X11Options", NULL);
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek }
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek return 0;
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek}
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmekstatic int find_converted_keymap(Context *c, char **new_keymap) {
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek const char *dir;
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek _cleanup_free_ char *n;
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek if (c->x11_variant)
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek n = strjoin(c->x11_layout, "-", c->x11_variant, NULL);
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek else
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek n = strdup(c->x11_layout);
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek if (!n)
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek return -ENOMEM;
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS) {
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek _cleanup_free_ char *p = NULL, *pz = NULL;
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek p = strjoin(dir, "xkb/", n, ".map", NULL);
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek pz = strjoin(dir, "xkb/", n, ".map.gz", NULL);
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek if (!p || !pz)
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek return -ENOMEM;
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek if (access(p, F_OK) == 0 || access(pz, F_OK) == 0) {
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek *new_keymap = n;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek n = NULL;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return 1;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return 0;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek}
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekstatic int find_legacy_keymap(Context *c, char **new_keymap) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek _cleanup_fclose_ FILE *f;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek unsigned n = 0;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek unsigned best_matching = 0;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek f = fopen(SYSTEMD_KBD_MODEL_MAP, "re");
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (!f)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return -errno;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek for (;;) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek _cleanup_strv_free_ char **a = NULL;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek unsigned matching = 0;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek int r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek r = read_next_mapping(f, &n, &a);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (r < 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (r == 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek break;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek /* Determine how well matching this entry is */
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (streq_ptr(c->x11_layout, a[1]))
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek /* If we got an exact match, this is best */
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt matching = 10;
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt else {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek size_t x;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek x = strcspn(c->x11_layout, ",");
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek /* We have multiple X layouts, look for an
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek * entry that matches our key with everything
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek * but the first layout stripped off. */
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (x > 0 &&
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek strlen(a[1]) == x &&
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek strneq(c->x11_layout, a[1], x))
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek matching = 5;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek else {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek size_t w;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek /* If that didn't work, strip off the
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek * other layouts from the entry, too */
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek w = strcspn(a[1], ",");
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (x > 0 && x == w &&
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek memcmp(c->x11_layout, a[1], x) == 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek matching = 1;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering }
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering if (matching > 0 &&
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering streq_ptr(c->x11_model, a[2])) {
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering matching++;
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering if (streq_ptr(c->x11_variant, a[3])) {
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering matching++;
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering if (streq_ptr(c->x11_options, a[4]))
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek matching++;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek /* The best matching entry so far, then let's save that */
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek if (matching > best_matching) {
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek best_matching = matching;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek free(*new_keymap);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek *new_keymap = strdup(a[0]);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (!*new_keymap)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return -ENOMEM;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek }
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek }
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return 0;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek}
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic int x11_convert_to_vconsole(Context *c, sd_bus *bus) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek bool modified = false;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek int r;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek assert(bus);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek if (isempty(c->x11_layout)) {
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek modified =
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek !isempty(c->vc_keymap) ||
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek !isempty(c->vc_keymap_toggle);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek context_free_x11(c);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek } else {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek char *new_keymap = NULL;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = find_converted_keymap(c, &new_keymap);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (r < 0)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek else if (r == 0) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek r = find_legacy_keymap(c, &new_keymap);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (r < 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (!streq_ptr(c->vc_keymap, new_keymap)) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek free_and_replace(&c->vc_keymap, new_keymap);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek free_and_replace(&c->vc_keymap_toggle, NULL);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek modified = true;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek } else
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek free(new_keymap);
c33b329709ebe2755181980a050d02ec7c81ed87Michal Schmidt }
c33b329709ebe2755181980a050d02ec7c81ed87Michal Schmidt
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (modified) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek r = vconsole_write_data(c);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (r < 0)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek log_error("Failed to set virtual console keymap: %s", strerror(-r));
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek sd_bus_emit_properties_changed(bus,
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek "/org/freedesktop/locale1",
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek "org.freedesktop.locale1",
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek "VConsoleKeymap", "VConsoleKeymapToggle", NULL);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return vconsole_reload(bus);
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek }
4015ac5c321f34784f73bd91ae9d7855ed663e5eLennart Poettering
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek return 0;
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek}
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic int property_get_locale(
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek sd_bus *bus,
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek const char *path,
2cf4172a71860c6e44edd27a3b68047ae062d7fcLennart Poettering const char *interface,
2cf4172a71860c6e44edd27a3b68047ae062d7fcLennart Poettering const char *property,
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek sd_bus_message *reply,
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek void *userdata,
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek sd_bus_error *error) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek Context *c = userdata;
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek _cleanup_strv_free_ char **l = NULL;
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmek int p, q;
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmek
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmek l = new0(char*, _LOCALE_MAX+1);
d71839afd88589247d8dd42b2b09d024f521749dZbigniew Jędrzejewski-Szmek if (!l)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return -ENOMEM;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek for (p = 0, q = 0; p < _LOCALE_MAX; p++) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek char *t;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (isempty(c->locale[p]))
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek continue;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (asprintf(&t, "%s=%s", names[p], c->locale[p]) < 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return -ENOMEM;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek l[q++] = t;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek }
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return sd_bus_message_append_strv(reply, l);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek}
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic int method_set_locale(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek Context *c = userdata;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek _cleanup_strv_free_ char **l = NULL;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek char **i;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek int interactive;
36d4739a68c3edafe4d145d525a26de4ef0b8e5aZbigniew Jędrzejewski-Szmek bool modified = false;
36d4739a68c3edafe4d145d525a26de4ef0b8e5aZbigniew Jędrzejewski-Szmek bool passed[_LOCALE_MAX] = {};
36d4739a68c3edafe4d145d525a26de4ef0b8e5aZbigniew Jędrzejewski-Szmek int p;
36d4739a68c3edafe4d145d525a26de4ef0b8e5aZbigniew Jędrzejewski-Szmek int r;
36d4739a68c3edafe4d145d525a26de4ef0b8e5aZbigniew Jędrzejewski-Szmek
36d4739a68c3edafe4d145d525a26de4ef0b8e5aZbigniew Jędrzejewski-Szmek r = bus_message_read_strv_extend(m, &l);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (r < 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return r;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek r = sd_bus_message_read_basic(m, 'b', &interactive);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (r < 0)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return r;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek /* Check whether a variable changed and if so valid */
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek STRV_FOREACH(i, l) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek bool valid = false;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek for (p = 0; p < _LOCALE_MAX; p++) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek size_t k;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek k = strlen(names[p]);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (startswith(*i, names[p]) &&
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek (*i)[k] == '=' &&
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek string_is_safe((*i) + k + 1)) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek valid = true;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek passed[p] = true;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (!streq_ptr(*i + k + 1, c->locale[p]))
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek modified = true;
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek break;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek }
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek }
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (!valid)
af4ec4309e8f82aad87a8d574785c12f8763d5f8Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Locale data.");
af4ec4309e8f82aad87a8d574785c12f8763d5f8Lennart Poettering }
af4ec4309e8f82aad87a8d574785c12f8763d5f8Lennart Poettering
af4ec4309e8f82aad87a8d574785c12f8763d5f8Lennart Poettering /* Check whether a variable is unset */
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (!modified) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek for (p = 0; p < _LOCALE_MAX; p++)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (!isempty(c->locale[p]) && !passed[p]) {
36d4739a68c3edafe4d145d525a26de4ef0b8e5aZbigniew Jędrzejewski-Szmek modified = true;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek break;
}
}
if (modified) {
r = bus_verify_polkit_async(bus, &c->polkit_registry, m,
"org.freedesktop.locale1.set-locale", interactive,
error, method_set_locale, c);
if (r < 0)
return r;
if (r == 0)
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;
k = strlen(names[p]);
if (startswith(*i, names[p]) && (*i)[k] == '=') {
char *t;
t = strdup(*i + k + 1);
if (!t)
return -ENOMEM;
free(c->locale[p]);
c->locale[p] = t;
break;
}
}
}
for (p = 0; p < _LOCALE_MAX; p++) {
if (passed[p])
continue;
free_and_replace(&c->locale[p], NULL);
}
locale_simplify(c);
r = locale_write_data(c);
if (r < 0) {
log_error("Failed to set locale: %s", strerror(-r));
return sd_bus_error_set_errnof(error, r, "Failed to set locale: %s", strerror(-r));
}
locale_update_system_manager(c, bus);
log_info("Changed locale information.");
sd_bus_emit_properties_changed(bus,
"/org/freedesktop/locale1",
"org.freedesktop.locale1",
"Locale", NULL);
}
return sd_bus_reply_method_return(m, NULL);
}
static int method_set_vc_keyboard(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
Context *c = userdata;
const char *keymap, *keymap_toggle;
int convert, interactive;
int r;
r = sd_bus_message_read(m, "ssbb", &keymap, &keymap_toggle, &convert, &interactive);
if (r < 0)
return r;
if (isempty(keymap))
keymap = NULL;
if (isempty(keymap_toggle))
keymap_toggle = NULL;
if (!streq_ptr(keymap, c->vc_keymap) ||
!streq_ptr(keymap_toggle, c->vc_keymap_toggle)) {
if ((keymap && (!filename_is_safe(keymap) || !string_is_safe(keymap))) ||
(keymap_toggle && (!filename_is_safe(keymap_toggle) || !string_is_safe(keymap_toggle))))
return sd_bus_error_set_errnof(error, r, "Received invalid keymap data: %s", -EINVAL);
r = bus_verify_polkit_async(bus, &c->polkit_registry, m,
"org.freedesktop.locale1.set-keyboard",
interactive, error, method_set_vc_keyboard, c);
if (r < 0)
return r;
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
if (free_and_copy(&c->vc_keymap, keymap) < 0 ||
free_and_copy(&c->vc_keymap_toggle, keymap_toggle) < 0)
return -ENOMEM;
r = vconsole_write_data(c);
if (r < 0) {
log_error("Failed to set virtual console keymap: %s", strerror(-r));
return sd_bus_error_set_errnof(error, r, "Failed to set virtual console keymap: %s", strerror(-r));
}
log_info("Changed virtual console keymap to '%s'", strempty(c->vc_keymap));
r = vconsole_reload(bus);
if (r < 0)
log_error("Failed to request keymap reload: %s", strerror(-r));
sd_bus_emit_properties_changed(bus,
"/org/freedesktop/locale1",
"org.freedesktop.locale1",
"VConsoleKeymap", "VConsoleKeymapToggle", NULL);
if (convert) {
r = vconsole_convert_to_x11(c, bus);
if (r < 0)
log_error("Failed to convert keymap data: %s", strerror(-r));
}
}
return sd_bus_reply_method_return(m, NULL);
}
static int method_set_x11_keyboard(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
Context *c = userdata;
const char *layout, *model, *variant, *options;
int convert, interactive;
int r;
r = sd_bus_message_read(m, "ssssbb", &layout, &model, &variant, &options, &convert, &interactive);
if (r < 0)
return r;
if (isempty(layout))
layout = NULL;
if (isempty(model))
model = NULL;
if (isempty(variant))
variant = NULL;
if (isempty(options))
options = NULL;
if (!streq_ptr(layout, c->x11_layout) ||
!streq_ptr(model, c->x11_model) ||
!streq_ptr(variant, c->x11_variant) ||
!streq_ptr(options, c->x11_options)) {
if ((layout && !string_is_safe(layout)) ||
(model && !string_is_safe(model)) ||
(variant && !string_is_safe(variant)) ||
(options && !string_is_safe(options)))
return sd_bus_error_set_errnof(error, r, "Received invalid keyboard data: %s", -EINVAL);
r = bus_verify_polkit_async(bus, &c->polkit_registry, m,
"org.freedesktop.locale1.set-keyboard",
interactive, error, method_set_x11_keyboard, c);
if (r < 0)
return r;
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
if (free_and_copy(&c->x11_layout, layout) < 0 ||
free_and_copy(&c->x11_model, model) < 0 ||
free_and_copy(&c->x11_variant, variant) < 0 ||
free_and_copy(&c->x11_options, options) < 0)
return -ENOMEM;
r = write_data_x11(c);
if (r < 0) {
log_error("Failed to set X11 keyboard layout: %s", strerror(-r));
return sd_bus_error_set_errnof(error, r, "Failed to set X11 keyboard layout: %s", strerror(-r));
}
log_info("Changed X11 keyboard layout to '%s'", strempty(c->x11_layout));
sd_bus_emit_properties_changed(bus,
"/org/freedesktop/locale1",
"org.freedesktop.locale1",
"X11Layout" "X11Model" "X11Variant" "X11Options", NULL);
if (convert) {
r = x11_convert_to_vconsole(c, bus);
if (r < 0)
log_error("Failed to convert keymap data: %s", strerror(-r));
}
}
return sd_bus_reply_method_return(m, NULL);
}
static const sd_bus_vtable locale_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Locale", "as", property_get_locale, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
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("SetLocale", "asb", NULL, method_set_locale, SD_BUS_VTABLE_UNPRIVILEGED),
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),
SD_BUS_VTABLE_END
};
static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
_cleanup_bus_unref_ sd_bus *bus = NULL;
int r;
assert(c);
assert(event);
assert(_bus);
r = sd_bus_default_system(&bus);
if (r < 0) {
log_error("Failed to get system bus connection: %s", strerror(-r));
return r;
}
r = sd_bus_add_object_vtable(bus, "/org/freedesktop/locale1", "org.freedesktop.locale1", locale_vtable, c);
if (r < 0) {
log_error("Failed to register object: %s", strerror(-r));
return r;
}
r = sd_bus_request_name(bus, "org.freedesktop.locale1", 0);
if (r < 0) {
log_error("Failed to register name: %s", strerror(-r));
return r;
}
r = sd_bus_attach_event(bus, event, 0);
if (r < 0) {
log_error("Failed to attach bus to event loop: %s", strerror(-r));
return r;
}
*_bus = bus;
bus = NULL;
return 0;
}
int main(int argc, char *argv[]) {
Context context = {};
_cleanup_event_unref_ sd_event *event = NULL;
_cleanup_bus_unref_ sd_bus *bus = NULL;
int r;
log_set_target(LOG_TARGET_AUTO);
log_parse_environment();
log_open();
umask(0022);
label_init("/etc");
if (argc != 1) {
log_error("This program takes no arguments.");
r = -EINVAL;
goto finish;
}
r = sd_event_default(&event);
if (r < 0) {
log_error("Failed to allocate event loop: %s", strerror(-r));
goto finish;
}
sd_event_set_watchdog(event, true);
r = connect_bus(&context, event, &bus);
if (r < 0)
goto finish;
r = context_read_data(&context);
if (r < 0) {
log_error("Failed to read locale data: %s", strerror(-r));
goto finish;
}
r = bus_event_loop_with_idle(event, bus, "org.freedesktop.locale1", DEFAULT_EXIT_USEC);
if (r < 0) {
log_error("Failed to run event loop: %s", strerror(-r));
goto finish;
}
finish:
context_free(&context, bus);
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}