localed.c revision 502f961425f9dea1a85239766a3189695194da63
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering/***
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering This file is part of systemd.
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering Copyright 2011 Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering Copyright 2013 Kay Sievers
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering systemd is free software; you can redistribute it and/or modify it
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering under the terms of the GNU Lesser General Public License as published by
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (at your option) any later version.
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering systemd is distributed in the hope that it will be useful, but
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering Lesser General Public License for more details.
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering You should have received a copy of the GNU Lesser General Public License
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering***/
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include <errno.h>
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include <string.h>
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include <unistd.h>
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include <sys/capability.h>
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering#include "sd-bus.h"
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering#include "util.h"
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering#include "mkdir.h"
cee5e9a7ca75f05d4a0f7759566e657587a500d5Lennart Poettering#include "strv.h"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include "def.h"
bdfb9e7f7c315af5a6755ac4701b696ce2305a19Lennart Poettering#include "env-util.h"
81527be142678057215665be66e4b3c8306a7ab3Lennart Poettering#include "fileio.h"
81527be142678057215665be66e4b3c8306a7ab3Lennart Poettering#include "fileio-label.h"
81527be142678057215665be66e4b3c8306a7ab3Lennart Poettering#include "label.h"
81527be142678057215665be66e4b3c8306a7ab3Lennart Poettering#include "bus-util.h"
ba1261bc02693ac8a7712ade14aab8e22989ba88Lennart Poettering#include "bus-error.h"
ba1261bc02693ac8a7712ade14aab8e22989ba88Lennart Poettering#include "bus-message.h"
ba1261bc02693ac8a7712ade14aab8e22989ba88Lennart Poettering#include "event-util.h"
ba1261bc02693ac8a7712ade14aab8e22989ba88Lennart Poettering#include "locale-util.h"
49e942b2bc9fdedba79cd266a076ce9c9d91fc13Kay Sievers
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringenum {
cec736d21ff86c4ac81b4d306ddba2120333818cLennart Poettering /* We don't list LC_ALL here on purpose. People should be
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering * using LANG instead. */
69e5d42db09dfb638bc74055c33bb2645f81563dLennart Poettering LOCALE_LANG,
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering LOCALE_LANGUAGE,
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering LOCALE_LC_CTYPE,
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering LOCALE_LC_NUMERIC,
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering LOCALE_LC_TIME,
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering LOCALE_LC_COLLATE,
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering LOCALE_LC_MONETARY,
89fef99014662a5a63e7deaedd6292b7fb4ab2f8Lennart Poettering LOCALE_LC_MESSAGES,
e6960940b6dc5ab81eb2fca4061c333e1795f38dLennart Poettering LOCALE_LC_PAPER,
d2bd7630d7ebbf9a86cca96e39d56efd4558ead4Lennart Poettering LOCALE_LC_NAME,
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering LOCALE_LC_ADDRESS,
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering LOCALE_LC_TELEPHONE,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering LOCALE_LC_MEASUREMENT,
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering LOCALE_LC_IDENTIFICATION,
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering _LOCALE_MAX
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering};
e6520a0fcebb4d5e07f4c81a51382501b0beb22fLennart Poettering
e6520a0fcebb4d5e07f4c81a51382501b0beb22fLennart Poetteringstatic const char * const names[_LOCALE_MAX] = {
e6520a0fcebb4d5e07f4c81a51382501b0beb22fLennart Poettering [LOCALE_LANG] = "LANG",
79c077224be5a868d0bba66972ef9546dae85977Kay Sievers [LOCALE_LANGUAGE] = "LANGUAGE",
e6520a0fcebb4d5e07f4c81a51382501b0beb22fLennart Poettering [LOCALE_LC_CTYPE] = "LC_CTYPE",
e6520a0fcebb4d5e07f4c81a51382501b0beb22fLennart Poettering [LOCALE_LC_NUMERIC] = "LC_NUMERIC",
8a0f04e6a283cc6734ee09a20305c13e09ba0418Lennart Poettering [LOCALE_LC_TIME] = "LC_TIME",
8a0f04e6a283cc6734ee09a20305c13e09ba0418Lennart Poettering [LOCALE_LC_COLLATE] = "LC_COLLATE",
8a0f04e6a283cc6734ee09a20305c13e09ba0418Lennart Poettering [LOCALE_LC_MONETARY] = "LC_MONETARY",
8a0f04e6a283cc6734ee09a20305c13e09ba0418Lennart Poettering [LOCALE_LC_MESSAGES] = "LC_MESSAGES",
cab8ac60837b489b27a247990f741315c71cb389Lennart Poettering [LOCALE_LC_PAPER] = "LC_PAPER",
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering [LOCALE_LC_NAME] = "LC_NAME",
de97b26ac5e29063632312ec1a20eb6318ca924cLennart Poettering [LOCALE_LC_ADDRESS] = "LC_ADDRESS",
de97b26ac5e29063632312ec1a20eb6318ca924cLennart Poettering [LOCALE_LC_TELEPHONE] = "LC_TELEPHONE",
de97b26ac5e29063632312ec1a20eb6318ca924cLennart Poettering [LOCALE_LC_MEASUREMENT] = "LC_MEASUREMENT",
9cfb57c989b62d11c073c77179df4bb7fa19f35dLennart Poettering [LOCALE_LC_IDENTIFICATION] = "LC_IDENTIFICATION"
9cfb57c989b62d11c073c77179df4bb7fa19f35dLennart Poettering};
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poetteringtypedef struct Context {
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering char *locale[_LOCALE_MAX];
205c4d1d6a3f5343f970abf20283d69dcec359edLennart Poettering
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering char *x11_layout;
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering char *x11_model;
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering char *x11_variant;
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering char *x11_options;
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering char *vc_keymap;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering char *vc_keymap_toggle;
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering Hashmap *polkit_registry;
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering} Context;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poetteringstatic const char* nonempty(const char *s) {
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering return isempty(s) ? NULL : s;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering}
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poetteringstatic void free_and_replace(char **s, char *v) {
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering free(*s);
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering *s = v;
9cfb57c989b62d11c073c77179df4bb7fa19f35dLennart Poettering}
9cfb57c989b62d11c073c77179df4bb7fa19f35dLennart Poettering
9cfb57c989b62d11c073c77179df4bb7fa19f35dLennart Poetteringstatic void context_free_x11(Context *c) {
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering free_and_replace(&c->x11_layout, NULL);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering free_and_replace(&c->x11_model, NULL);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering free_and_replace(&c->x11_variant, NULL);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering free_and_replace(&c->x11_options, NULL);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering}
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poetteringstatic void context_free_vconsole(Context *c) {
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering free_and_replace(&c->vc_keymap, NULL);
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering free_and_replace(&c->vc_keymap_toggle, NULL);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering}
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poetteringstatic void context_free_locale(Context *c) {
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering int p;
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering for (p = 0; p < _LOCALE_MAX; p++)
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering free_and_replace(&c->locale[p], NULL);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering}
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poetteringstatic void context_free(Context *c) {
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering context_free_locale(c);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering context_free_x11(c);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering context_free_vconsole(c);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering bus_verify_polkit_async_registry_free(c->polkit_registry);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering};
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poetteringstatic void locale_simplify(Context *c) {
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering int p;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering for (p = LOCALE_LANG+1; p < _LOCALE_MAX; p++)
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering if (isempty(c->locale[p]) || streq_ptr(c->locale[LOCALE_LANG], c->locale[p]))
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering free_and_replace(&c->locale[p], NULL);
34a35eced40860181757abe5ec00ac0e5d8d0225Lennart Poettering}
34a35eced40860181757abe5ec00ac0e5d8d0225Lennart Poettering
34a35eced40860181757abe5ec00ac0e5d8d0225Lennart Poetteringstatic int locale_read_data(Context *c) {
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering int r;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering context_free_locale(c);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
c042179388f329fb1e45b00e1a533a0dc27fb9aeLennart Poettering r = parse_env_file("/etc/locale.conf", NEWLINE,
c042179388f329fb1e45b00e1a533a0dc27fb9aeLennart Poettering "LANG", &c->locale[LOCALE_LANG],
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering "LANGUAGE", &c->locale[LOCALE_LANGUAGE],
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering "LC_CTYPE", &c->locale[LOCALE_LC_CTYPE],
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering "LC_NUMERIC", &c->locale[LOCALE_LC_NUMERIC],
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering "LC_TIME", &c->locale[LOCALE_LC_TIME],
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering "LC_COLLATE", &c->locale[LOCALE_LC_COLLATE],
a3a52c0fd0c2597bf8233730c3ed3408affe0c9fLennart Poettering "LC_MONETARY", &c->locale[LOCALE_LC_MONETARY],
a3a52c0fd0c2597bf8233730c3ed3408affe0c9fLennart Poettering "LC_MESSAGES", &c->locale[LOCALE_LC_MESSAGES],
a3a52c0fd0c2597bf8233730c3ed3408affe0c9fLennart Poettering "LC_PAPER", &c->locale[LOCALE_LC_PAPER],
a3a52c0fd0c2597bf8233730c3ed3408affe0c9fLennart Poettering "LC_NAME", &c->locale[LOCALE_LC_NAME],
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering "LC_ADDRESS", &c->locale[LOCALE_LC_ADDRESS],
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering "LC_TELEPHONE", &c->locale[LOCALE_LC_TELEPHONE],
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering "LC_MEASUREMENT", &c->locale[LOCALE_LC_MEASUREMENT],
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering "LC_IDENTIFICATION", &c->locale[LOCALE_LC_IDENTIFICATION],
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering NULL);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering if (r == -ENOENT) {
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering int p;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering /* Fill in what we got passed from systemd. */
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering for (p = 0; p < _LOCALE_MAX; p++) {
9cfb57c989b62d11c073c77179df4bb7fa19f35dLennart Poettering assert(names[p]);
9cfb57c989b62d11c073c77179df4bb7fa19f35dLennart Poettering
9cfb57c989b62d11c073c77179df4bb7fa19f35dLennart Poettering r = free_and_strdup(&c->locale[p],
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering nonempty(getenv(names[p])));
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering if (r < 0)
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering return r;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering }
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering r = 0;
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering }
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering locale_simplify(c);
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering return r;
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering}
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poetteringstatic int vconsole_read_data(Context *c) {
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering int r;
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering context_free_vconsole(c);
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering r = parse_env_file("/etc/vconsole.conf", NEWLINE,
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering "KEYMAP", &c->vc_keymap,
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering "KEYMAP_TOGGLE", &c->vc_keymap_toggle,
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering NULL);
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering if (r < 0 && r != -ENOENT)
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering return r;
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering return 0;
e6520a0fcebb4d5e07f4c81a51382501b0beb22fLennart Poettering}
e6520a0fcebb4d5e07f4c81a51382501b0beb22fLennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poetteringstatic int x11_read_data(Context *c) {
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering _cleanup_fclose_ FILE *f;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering char line[LINE_MAX];
e6520a0fcebb4d5e07f4c81a51382501b0beb22fLennart Poettering bool in_section = false;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering int r;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering context_free_x11(c);
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering f = fopen("/etc/X11/xorg.conf.d/00-keyboard.conf", "re");
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering if (!f)
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering return errno == ENOENT ? 0 : -errno;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering while (fgets(line, sizeof(line), f)) {
e6520a0fcebb4d5e07f4c81a51382501b0beb22fLennart Poettering char *l;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering char_array_0(line);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering l = strstrip(line);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (l[0] == 0 || l[0] == '#')
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering continue;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (in_section && first_word(l, "Option")) {
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering _cleanup_strv_free_ char **a = NULL;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering r = strv_split_quoted(&a, l);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (r < 0)
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering return r;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (strv_length(a) == 3) {
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (streq(a[1], "XkbLayout")) {
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering free_and_replace(&c->x11_layout, a[2]);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering a[2] = NULL;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering } else if (streq(a[1], "XkbModel")) {
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering free_and_replace(&c->x11_model, a[2]);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering a[2] = NULL;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering } else if (streq(a[1], "XkbVariant")) {
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering free_and_replace(&c->x11_variant, a[2]);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering a[2] = NULL;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering } else if (streq(a[1], "XkbOptions")) {
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering free_and_replace(&c->x11_options, a[2]);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering a[2] = NULL;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering }
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering }
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering } else if (!in_section && first_word(l, "Section")) {
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering _cleanup_strv_free_ char **a = NULL;
e6520a0fcebb4d5e07f4c81a51382501b0beb22fLennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering r = strv_split_quoted(&a, l);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (r < 0)
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering return -ENOMEM;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (strv_length(a) == 2 && streq(a[1], "InputClass"))
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering in_section = true;
3fbf9cbb02690e40cd65802e777519f3f3c8d88aLennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering } else if (in_section && first_word(l, "EndSection"))
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering in_section = false;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering }
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering return 0;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering}
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poetteringstatic int context_read_data(Context *c) {
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering int r, q, p;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering r = locale_read_data(c);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering q = vconsole_read_data(c);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering p = x11_read_data(c);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
3fbf9cbb02690e40cd65802e777519f3f3c8d88aLennart Poettering return r < 0 ? r : q < 0 ? q : p;
3fbf9cbb02690e40cd65802e777519f3f3c8d88aLennart Poettering}
3fbf9cbb02690e40cd65802e777519f3f3c8d88aLennart Poettering
3fbf9cbb02690e40cd65802e777519f3f3c8d88aLennart Poetteringstatic int locale_write_data(Context *c, char ***settings) {
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering int r, p;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering _cleanup_strv_free_ char **l = NULL;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering /* Set values will be returned as strv in *settings on success. */
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering r = load_env_file(NULL, "/etc/locale.conf", NULL, &l);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (r < 0 && r != -ENOENT)
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering return r;
cab8ac60837b489b27a247990f741315c71cb389Lennart Poettering
cab8ac60837b489b27a247990f741315c71cb389Lennart Poettering for (p = 0; p < _LOCALE_MAX; p++) {
cab8ac60837b489b27a247990f741315c71cb389Lennart Poettering _cleanup_free_ char *t = NULL;
cab8ac60837b489b27a247990f741315c71cb389Lennart Poettering char **u;
cab8ac60837b489b27a247990f741315c71cb389Lennart Poettering
cab8ac60837b489b27a247990f741315c71cb389Lennart Poettering assert(names[p]);
cab8ac60837b489b27a247990f741315c71cb389Lennart Poettering
eb53b74f7e2f83d936b35107806a157fdffdbf5aLennart Poettering if (isempty(c->locale[p])) {
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering l = strv_env_unset(l, names[p]);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering continue;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering }
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (asprintf(&t, "%s=%s", names[p], c->locale[p]) < 0)
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering return -ENOMEM;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering u = strv_env_set(l, t);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (!u)
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering return -ENOMEM;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering strv_free(l);
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering l = u;
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering }
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering
f4b4781191e8edfb5690e4447166e3ba7bcb48f5Lennart Poettering if (strv_isempty(l)) {
b1a0ab714863ae77e4683820757b3f49c03a0049Lennart Poettering if (unlink("/etc/locale.conf") < 0)
b1a0ab714863ae77e4683820757b3f49c03a0049Lennart Poettering return errno == ENOENT ? 0 : -errno;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering
b1a0ab714863ae77e4683820757b3f49c03a0049Lennart Poettering return 0;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering }
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering r = write_env_file_label("/etc/locale.conf", l);
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering if (r < 0)
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering return r;
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering *settings = l;
499fb2152f8518796607dd0406698cb6ce4c7098Sjoerd Simons l = NULL;
499fb2152f8518796607dd0406698cb6ce4c7098Sjoerd Simons return 0;
499fb2152f8518796607dd0406698cb6ce4c7098Sjoerd Simons}
499fb2152f8518796607dd0406698cb6ce4c7098Sjoerd Simons
5e62067d08d989ab98b12497a9b27a877de8515bLennart Poetteringstatic int locale_update_system_manager(Context *c, sd_bus *bus) {
5e62067d08d989ab98b12497a9b27a877de8515bLennart Poettering _cleanup_free_ char **l_unset = NULL;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering _cleanup_strv_free_ char **l_set = NULL;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering sd_bus_error error = SD_BUS_ERROR_NULL;
eb53b74f7e2f83d936b35107806a157fdffdbf5aLennart Poettering unsigned c_set, c_unset, p;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering int r;
499fb2152f8518796607dd0406698cb6ce4c7098Sjoerd Simons
499fb2152f8518796607dd0406698cb6ce4c7098Sjoerd Simons assert(bus);
499fb2152f8518796607dd0406698cb6ce4c7098Sjoerd Simons
499fb2152f8518796607dd0406698cb6ce4c7098Sjoerd Simons l_unset = new0(char*, _LOCALE_MAX);
499fb2152f8518796607dd0406698cb6ce4c7098Sjoerd Simons if (!l_unset)
5e62067d08d989ab98b12497a9b27a877de8515bLennart Poettering return -ENOMEM;
5e62067d08d989ab98b12497a9b27a877de8515bLennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering l_set = new0(char*, _LOCALE_MAX);
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering if (!l_set)
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering return -ENOMEM;
eb53b74f7e2f83d936b35107806a157fdffdbf5aLennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering for (p = 0, c_set = 0, c_unset = 0; p < _LOCALE_MAX; p++) {
499fb2152f8518796607dd0406698cb6ce4c7098Sjoerd Simons assert(names[p]);
499fb2152f8518796607dd0406698cb6ce4c7098Sjoerd Simons
499fb2152f8518796607dd0406698cb6ce4c7098Sjoerd Simons if (isempty(c->locale[p]))
499fb2152f8518796607dd0406698cb6ce4c7098Sjoerd Simons l_unset[c_set++] = (char*) names[p];
5e62067d08d989ab98b12497a9b27a877de8515bLennart Poettering else {
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering char *s;
5e62067d08d989ab98b12497a9b27a877de8515bLennart Poettering
5e62067d08d989ab98b12497a9b27a877de8515bLennart Poettering if (asprintf(&s, "%s=%s", names[p], c->locale[p]) < 0)
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering return -ENOMEM;
b1a0ab714863ae77e4683820757b3f49c03a0049Lennart Poettering
b1a0ab714863ae77e4683820757b3f49c03a0049Lennart Poettering l_set[c_unset++] = s;
b1a0ab714863ae77e4683820757b3f49c03a0049Lennart Poettering }
b1a0ab714863ae77e4683820757b3f49c03a0049Lennart Poettering }
b1a0ab714863ae77e4683820757b3f49c03a0049Lennart Poettering
b1a0ab714863ae77e4683820757b3f49c03a0049Lennart Poettering assert(c_set + c_unset == _LOCALE_MAX);
b1a0ab714863ae77e4683820757b3f49c03a0049Lennart Poettering r = sd_bus_message_new_method_call(bus, &m,
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering "org.freedesktop.systemd1",
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering "/org/freedesktop/systemd1",
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering "org.freedesktop.systemd1.Manager",
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering "UnsetAndSetEnvironment");
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering if (r < 0)
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering return r;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering r = sd_bus_message_append_strv(m, l_unset);
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering if (r < 0)
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering return r;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering r = sd_bus_message_append_strv(m, l_set);
99add6fd0b8f4307ed79256e25f38da318e795c4Lennart Poettering if (r < 0)
99add6fd0b8f4307ed79256e25f38da318e795c4Lennart Poettering return r;
0d0f0c50d3a1d90f03972a6abb82e6413daaa583Shawn Landden
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering r = sd_bus_call(bus, m, 0, &error, NULL);
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering if (r < 0)
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering log_error("Failed to update the manager environment: %s", strerror(-r));
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering return 0;
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering}
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poetteringstatic int vconsole_write_data(Context *c) {
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering int r;
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering _cleanup_strv_free_ char **l = NULL;
99add6fd0b8f4307ed79256e25f38da318e795c4Lennart Poettering
99add6fd0b8f4307ed79256e25f38da318e795c4Lennart Poettering r = load_env_file(NULL, "/etc/vconsole.conf", NULL, &l);
0d0f0c50d3a1d90f03972a6abb82e6413daaa583Shawn Landden if (r < 0 && r != -ENOENT)
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering return r;
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering if (isempty(c->vc_keymap))
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering l = strv_env_unset(l, "KEYMAP");
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering else {
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering _cleanup_free_ char *s = NULL;
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering char **u;
babfc09177c1e71cec6c1ef9602e265ed40cfe4fLennart Poettering
9cfb57c989b62d11c073c77179df4bb7fa19f35dLennart Poettering s = strappend("KEYMAP=", c->vc_keymap);
9cfb57c989b62d11c073c77179df4bb7fa19f35dLennart Poettering if (!s)
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering return -ENOMEM;
bc85bfee87e11317fbcd1160c9003860dc6edde9Lennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering u = strv_env_set(l, s);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering if (!u)
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering return -ENOMEM;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering strv_free(l);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering l = u;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering }
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering if (isempty(c->vc_keymap_toggle))
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering l = strv_env_unset(l, "KEYMAP_TOGGLE");
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering else {
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering _cleanup_free_ char *s = NULL;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering char **u;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering s = strappend("KEYMAP_TOGGLE=", c->vc_keymap_toggle);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering if (!s)
bad75c274a488715a845ff8e5ec3140036929e94Lennart Poettering return -ENOMEM;
bad75c274a488715a845ff8e5ec3140036929e94Lennart Poettering
bad75c274a488715a845ff8e5ec3140036929e94Lennart Poettering u = strv_env_set(l, s);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering if (!u)
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering return -ENOMEM;
783d2675eff73d1937bf8f78b368b1004c2d28c5Lennart Poettering
783d2675eff73d1937bf8f78b368b1004c2d28c5Lennart Poettering strv_free(l);
783d2675eff73d1937bf8f78b368b1004c2d28c5Lennart Poettering l = u;
783d2675eff73d1937bf8f78b368b1004c2d28c5Lennart Poettering }
783d2675eff73d1937bf8f78b368b1004c2d28c5Lennart Poettering
783d2675eff73d1937bf8f78b368b1004c2d28c5Lennart Poettering if (strv_isempty(l)) {
783d2675eff73d1937bf8f78b368b1004c2d28c5Lennart Poettering if (unlink("/etc/vconsole.conf") < 0)
783d2675eff73d1937bf8f78b368b1004c2d28c5Lennart Poettering return errno == ENOENT ? 0 : -errno;
783d2675eff73d1937bf8f78b368b1004c2d28c5Lennart Poettering
783d2675eff73d1937bf8f78b368b1004c2d28c5Lennart Poettering return 0;
783d2675eff73d1937bf8f78b368b1004c2d28c5Lennart Poettering }
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
783d2675eff73d1937bf8f78b368b1004c2d28c5Lennart Poettering return write_env_file_label("/etc/vconsole.conf", l);
783d2675eff73d1937bf8f78b368b1004c2d28c5Lennart Poettering}
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
783d2675eff73d1937bf8f78b368b1004c2d28c5Lennart Poetteringstatic int write_data_x11(Context *c) {
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering _cleanup_fclose_ FILE *f = NULL;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering _cleanup_free_ char *temp_path = NULL;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering int r;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering if (isempty(c->x11_layout) &&
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering isempty(c->x11_model) &&
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering isempty(c->x11_variant) &&
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering isempty(c->x11_options)) {
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering if (unlink("/etc/X11/xorg.conf.d/00-keyboard.conf") < 0)
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering return errno == ENOENT ? 0 : -errno;
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering return 0;
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering }
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering mkdir_p_label("/etc/X11/xorg.conf.d", 0755);
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering r = fopen_temporary("/etc/X11/xorg.conf.d/00-keyboard.conf", &f, &temp_path);
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering if (r < 0)
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering return r;
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering fchmod(fileno(f), 0644);
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering
c2a623d842af3a4d67e1f4e365f6d6a47f1c6cb4Lennart Poettering fputs("# Read and parsed by systemd-localed. It's probably wise not to edit this file\n"
c2a623d842af3a4d67e1f4e365f6d6a47f1c6cb4Lennart Poettering "# manually too freely.\n"
c2a623d842af3a4d67e1f4e365f6d6a47f1c6cb4Lennart Poettering "Section \"InputClass\"\n"
c2a623d842af3a4d67e1f4e365f6d6a47f1c6cb4Lennart Poettering " Identifier \"system-keyboard\"\n"
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering " MatchIsKeyboard \"on\"\n", f);
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering if (!isempty(c->x11_layout))
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering fprintf(f, " Option \"XkbLayout\" \"%s\"\n", c->x11_layout);
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering if (!isempty(c->x11_model))
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering fprintf(f, " Option \"XkbModel\" \"%s\"\n", c->x11_model);
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering if (!isempty(c->x11_variant))
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering fprintf(f, " Option \"XkbVariant\" \"%s\"\n", c->x11_variant);
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering if (!isempty(c->x11_options))
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering fprintf(f, " Option \"XkbOptions\" \"%s\"\n", c->x11_options);
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering fputs("EndSection\n", f);
71fa6f006f92831c0c02e844b4c35e4b7197c6d6Lennart Poettering fflush(f);
71fa6f006f92831c0c02e844b4c35e4b7197c6d6Lennart Poettering
71fa6f006f92831c0c02e844b4c35e4b7197c6d6Lennart Poettering if (ferror(f) || rename(temp_path, "/etc/X11/xorg.conf.d/00-keyboard.conf") < 0) {
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering r = -errno;
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering unlink("/etc/X11/xorg.conf.d/00-keyboard.conf");
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering unlink(temp_path);
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering return r;
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering } else
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering return 0;
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering}
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering
71fa6f006f92831c0c02e844b4c35e4b7197c6d6Lennart Poetteringstatic int vconsole_reload(sd_bus *bus) {
71fa6f006f92831c0c02e844b4c35e4b7197c6d6Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering int r;
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering assert(bus);
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering r = sd_bus_call_method(bus,
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering "org.freedesktop.systemd1",
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering "/org/freedesktop/systemd1",
32fca2d5b746b86bbbbd4f1b57064076cfc2ae4bLennart Poettering "org.freedesktop.systemd1.Manager",
32fca2d5b746b86bbbbd4f1b57064076cfc2ae4bLennart Poettering "RestartUnit",
32fca2d5b746b86bbbbd4f1b57064076cfc2ae4bLennart Poettering &error,
32fca2d5b746b86bbbbd4f1b57064076cfc2ae4bLennart Poettering NULL,
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering "ss", "systemd-vconsole-setup.service", "replace");
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering if (r < 0)
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering return r;
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering}
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poetteringstatic const char* strnulldash(const char *s) {
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering return isempty(s) || streq(s, "-") ? NULL : s;
8b38f3cc3eb73adf9536cb73d0f319e60d42ea0cLennart Poettering}
8b38f3cc3eb73adf9536cb73d0f319e60d42ea0cLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poetteringstatic int read_next_mapping(FILE *f, unsigned *n, char ***a) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(f);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(n);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(a);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering for (;;) {
8a0f04e6a283cc6734ee09a20305c13e09ba0418Lennart Poettering char line[LINE_MAX];
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering char *l, **b;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering errno = 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (!fgets(line, sizeof(line), f)) {
de190aef08bb267b645205a747762df573b36834Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (ferror(f))
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return errno ? -errno : -EIO;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering return 0;
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (*n) ++;
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering
ba1261bc02693ac8a7712ade14aab8e22989ba88Lennart Poettering l = strstrip(line);
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering if (l[0] == 0 || l[0] == '#')
ba1261bc02693ac8a7712ade14aab8e22989ba88Lennart Poettering continue;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
de190aef08bb267b645205a747762df573b36834Lennart Poettering r = strv_split_quoted(&b, l);
de190aef08bb267b645205a747762df573b36834Lennart Poettering if (r < 0)
de190aef08bb267b645205a747762df573b36834Lennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (strv_length(b) < 5) {
de190aef08bb267b645205a747762df573b36834Lennart Poettering log_error("Invalid line "SYSTEMD_KBD_MODEL_MAP":%u, ignoring.", *n);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering strv_free(b);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering continue;
de190aef08bb267b645205a747762df573b36834Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering *a = b;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 1;
de190aef08bb267b645205a747762df573b36834Lennart Poettering }
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering}
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int vconsole_convert_to_x11(Context *c, sd_bus *bus) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering bool modified = false;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(bus);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (isempty(c->vc_keymap)) {
de190aef08bb267b645205a747762df573b36834Lennart Poettering
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering modified =
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering !isempty(c->x11_layout) ||
5c3759bf8a3d418fa877e6a278f3150f404745b2Lennart Poettering !isempty(c->x11_model) ||
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering !isempty(c->x11_variant) ||
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering !isempty(c->x11_options);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering context_free_x11(c);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering } else {
de190aef08bb267b645205a747762df573b36834Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering unsigned n = 0;
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering f = fopen(SYSTEMD_KBD_MODEL_MAP, "re");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (!f)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -errno;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering for (;;) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering _cleanup_strv_free_ char **a = NULL;
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering int r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = read_next_mapping(f, &n, &a);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
de190aef08bb267b645205a747762df573b36834Lennart Poettering if (r == 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering break;
69e5d42db09dfb638bc74055c33bb2645f81563dLennart Poettering
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering if (!streq(c->vc_keymap, a[0]))
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering continue;
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering if (!streq_ptr(c->x11_layout, strnulldash(a[1])) ||
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering !streq_ptr(c->x11_model, strnulldash(a[2])) ||
69e5d42db09dfb638bc74055c33bb2645f81563dLennart Poettering !streq_ptr(c->x11_variant, strnulldash(a[3])) ||
69e5d42db09dfb638bc74055c33bb2645f81563dLennart Poettering !streq_ptr(c->x11_options, strnulldash(a[4]))) {
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering if (free_and_strdup(&c->x11_layout, strnulldash(a[1])) < 0 ||
ba1261bc02693ac8a7712ade14aab8e22989ba88Lennart Poettering free_and_strdup(&c->x11_model, strnulldash(a[2])) < 0 ||
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering free_and_strdup(&c->x11_variant, strnulldash(a[3])) < 0 ||
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering free_and_strdup(&c->x11_options, strnulldash(a[4])) < 0)
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering return -ENOMEM;
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering modified = true;
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering }
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering break;
ba1261bc02693ac8a7712ade14aab8e22989ba88Lennart Poettering }
ba1261bc02693ac8a7712ade14aab8e22989ba88Lennart Poettering }
ba1261bc02693ac8a7712ade14aab8e22989ba88Lennart Poettering
ba1261bc02693ac8a7712ade14aab8e22989ba88Lennart Poettering if (modified) {
ba1261bc02693ac8a7712ade14aab8e22989ba88Lennart Poettering int r;
ba1261bc02693ac8a7712ade14aab8e22989ba88Lennart Poettering
94fb446e55babb713fb24850455627acf30d999bLennart Poettering r = write_data_x11(c);
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering if (r < 0)
62bca2c657bf95fd1f69935eef09915afa5c69d9Eelco Dolstra log_error("Failed to set X11 keyboard layout: %s", strerror(-r));
62bca2c657bf95fd1f69935eef09915afa5c69d9Eelco Dolstra
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering log_info("Changed X11 keyboard layout to '%s' model '%s' variant '%s' options '%s'",
62bca2c657bf95fd1f69935eef09915afa5c69d9Eelco Dolstra strempty(c->x11_layout),
62bca2c657bf95fd1f69935eef09915afa5c69d9Eelco Dolstra strempty(c->x11_model),
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering strempty(c->x11_variant),
8a0f04e6a283cc6734ee09a20305c13e09ba0418Lennart Poettering strempty(c->x11_options));
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering sd_bus_emit_properties_changed(bus,
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering "/org/freedesktop/locale1",
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering "org.freedesktop.locale1",
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering "X11Layout", "X11Model", "X11Variant", "X11Options", NULL);
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering } else
8a0f04e6a283cc6734ee09a20305c13e09ba0418Lennart Poettering log_debug("X11 keyboard layout was not modified.");
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering return 0;
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering}
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poetteringstatic int find_converted_keymap(Context *c, char **new_keymap) {
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering const char *dir;
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering _cleanup_free_ char *n;
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering
8a0f04e6a283cc6734ee09a20305c13e09ba0418Lennart Poettering if (c->x11_variant)
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering n = strjoin(c->x11_layout, "-", c->x11_variant, NULL);
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering else
8a0f04e6a283cc6734ee09a20305c13e09ba0418Lennart Poettering n = strdup(c->x11_layout);
8a0f04e6a283cc6734ee09a20305c13e09ba0418Lennart Poettering if (!n)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -ENOMEM;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS) {
de190aef08bb267b645205a747762df573b36834Lennart Poettering _cleanup_free_ char *p = NULL, *pz = NULL;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering bool uncompressed;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering p = strjoin(dir, "xkb/", n, ".map", NULL);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering pz = strjoin(dir, "xkb/", n, ".map.gz", NULL);
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering if (!p || !pz)
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering return -ENOMEM;
ed49ef3f349bcd4f0483ba8254a2537fe8e9cd17Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uncompressed = access(p, F_OK) == 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (uncompressed || access(pz, F_OK) == 0) {
de190aef08bb267b645205a747762df573b36834Lennart Poettering log_debug("Found converted keymap %s at %s",
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n, uncompressed ? p : pz);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering *new_keymap = n;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n = NULL;
de190aef08bb267b645205a747762df573b36834Lennart Poettering return 1;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 0;
de190aef08bb267b645205a747762df573b36834Lennart Poettering}
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int find_legacy_keymap(Context *c, char **new_keymap) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering _cleanup_fclose_ FILE *f;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering unsigned n = 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering unsigned best_matching = 0;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
dca6219e04505e9fa10b32e71059ce2abfae1dadLennart Poettering f = fopen(SYSTEMD_KBD_MODEL_MAP, "re");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (!f)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -errno;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering for (;;) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering _cleanup_strv_free_ char **a = NULL;
69e5d42db09dfb638bc74055c33bb2645f81563dLennart Poettering unsigned matching = 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = read_next_mapping(f, &n, &a);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r == 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering break;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering /* Determine how well matching this entry is */
85d83bf41c8bdf55c10b7f845d81e5787ef6c295Lennart Poettering if (streq_ptr(c->x11_layout, a[1]))
94fb446e55babb713fb24850455627acf30d999bLennart Poettering /* If we got an exact match, this is best */
8a0f04e6a283cc6734ee09a20305c13e09ba0418Lennart Poettering matching = 10;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering else {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering size_t x;
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering x = strcspn(c->x11_layout, ",");
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering
33eb8abfa51d5bffbf8819215fafdd1123a4a8c0Lennart Poettering /* We have multiple X layouts, look for an
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering * entry that matches our key with everything
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering * but the first layout stripped off. */
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering if (x > 0 &&
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering strlen(a[1]) == x &&
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering strneq(c->x11_layout, a[1], x))
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering matching = 5;
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering else {
c51742d02981196f992aef5f3d72799f22ee89e0Lennart Poettering size_t w;
33eb8abfa51d5bffbf8819215fafdd1123a4a8c0Lennart Poettering
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering /* If that didn't work, strip off the
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering * other layouts from the entry, too */
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering w = strcspn(a[1], ",");
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering if (x > 0 && x == w &&
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering memcmp(c->x11_layout, a[1], x) == 0)
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering matching = 1;
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering }
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering }
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering if (matching > 0) {
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering if (isempty(c->x11_model) || streq_ptr(c->x11_model, a[2])) {
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering matching++;
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering if (streq_ptr(c->x11_variant, a[3])) {
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering matching++;
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering
62bca2c657bf95fd1f69935eef09915afa5c69d9Eelco Dolstra if (streq_ptr(c->x11_options, a[4]))
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering matching++;
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering /* The best matching entry so far, then let's save that */
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (matching >= MAX(best_matching, 1u)) {
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering log_debug("Found legacy keymap %s with score %u",
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering a[0], matching);
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering if (matching > best_matching) {
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering best_matching = matching;
783d2675eff73d1937bf8f78b368b1004c2d28c5Lennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering r = free_and_strdup(new_keymap, a[0]);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering if (r < 0)
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering return r;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering }
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering }
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering }
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
213ba152fdf7978773be5b8a72e040584765137fLennart Poettering return 0;
213ba152fdf7978773be5b8a72e040584765137fLennart Poettering}
213ba152fdf7978773be5b8a72e040584765137fLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poetteringstatic int x11_convert_to_vconsole(Context *c, sd_bus *bus) {
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering bool modified = false;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering int r;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering assert(bus);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering if (isempty(c->x11_layout)) {
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering modified =
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering !isempty(c->vc_keymap) ||
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering !isempty(c->vc_keymap_toggle);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering context_free_x11(c);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering } else {
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering char *new_keymap = NULL;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering r = find_converted_keymap(c, &new_keymap);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering if (r < 0)
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering return r;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering else if (r == 0) {
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering r = find_legacy_keymap(c, &new_keymap);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering if (r < 0)
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering return r;
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering }
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering if (!streq_ptr(c->vc_keymap, new_keymap)) {
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering free_and_replace(&c->vc_keymap, new_keymap);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering free_and_replace(&c->vc_keymap_toggle, NULL);
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering modified = true;
6e409ce10d134625626d1eddfd6152755ef1908dLennart Poettering } else
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering free(new_keymap);
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering }
ef63833d532dd86bdba63211e6a1363cbb3ef61dLennart Poettering
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering if (modified) {
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering r = vconsole_write_data(c);
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering if (r < 0)
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering log_error("Failed to set virtual console keymap: %s", strerror(-r));
62bca2c657bf95fd1f69935eef09915afa5c69d9Eelco Dolstra
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering log_info("Changed virtual console keymap to '%s' toggle '%s'",
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering strempty(c->vc_keymap), strempty(c->vc_keymap_toggle));
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering sd_bus_emit_properties_changed(bus,
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering "/org/freedesktop/locale1",
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering "org.freedesktop.locale1",
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering "VConsoleKeymap", "VConsoleKeymapToggle", NULL);
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering return vconsole_reload(bus);
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering } else
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering log_debug("Virtual console keymap was not modified.");
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering return 0;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering}
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poetteringstatic int property_get_locale(
b8156be03f71c53072c7126bb418410acbef6c81Lennart Poettering sd_bus *bus,
b8156be03f71c53072c7126bb418410acbef6c81Lennart Poettering const char *path,
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering const char *interface,
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering const char *property,
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering sd_bus_message *reply,
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering void *userdata,
205c4d1d6a3f5343f970abf20283d69dcec359edLennart Poettering sd_bus_error *error) {
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering Context *c = userdata;
b8156be03f71c53072c7126bb418410acbef6c81Lennart Poettering _cleanup_strv_free_ char **l = NULL;
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering int p, q;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering l = new0(char*, _LOCALE_MAX+1);
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering if (!l)
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering return -ENOMEM;
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering for (p = 0, q = 0; p < _LOCALE_MAX; p++) {
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering char *t;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
b7def684941808600c344f0be7a2b9fcdda97e0fLennart Poettering if (isempty(c->locale[p]))
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering continue;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering if (asprintf(&t, "%s=%s", names[p], c->locale[p]) < 0)
eb53b74f7e2f83d936b35107806a157fdffdbf5aLennart Poettering return -ENOMEM;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering l[q++] = t;
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering }
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering return sd_bus_message_append_strv(reply, l);
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering}
adf7d506b50af9ba398a9925c8cd47ba328e720cLennart Poettering
adf7d506b50af9ba398a9925c8cd47ba328e720cLennart Poetteringstatic int method_set_locale(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
adf7d506b50af9ba398a9925c8cd47ba328e720cLennart Poettering Context *c = userdata;
adf7d506b50af9ba398a9925c8cd47ba328e720cLennart Poettering _cleanup_strv_free_ char **l = NULL;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering char **i;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering int interactive;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering bool modified = false;
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering bool passed[_LOCALE_MAX] = {};
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering int p;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering int r;
b7def684941808600c344f0be7a2b9fcdda97e0fLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering r = bus_message_read_strv_extend(m, &l);
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering if (r < 0)
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering return r;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering r = sd_bus_message_read_basic(m, 'b', &interactive);
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering if (r < 0)
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering return r;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering /* Check whether a variable changed and if it is valid */
16e9f408fa9a9626059bdd6c89dc175e06b9e976Lennart Poettering STRV_FOREACH(i, l) {
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering bool valid = false;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering for (p = 0; p < _LOCALE_MAX; p++) {
adf7d506b50af9ba398a9925c8cd47ba328e720cLennart Poettering size_t k;
adf7d506b50af9ba398a9925c8cd47ba328e720cLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering k = strlen(names[p]);
adf7d506b50af9ba398a9925c8cd47ba328e720cLennart Poettering if (startswith(*i, names[p]) &&
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering (*i)[k] == '=' &&
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering locale_is_valid((*i) + k + 1)) {
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering valid = true;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering passed[p] = true;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering if (!streq_ptr(*i + k + 1, c->locale[p]))
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering modified = true;
b8156be03f71c53072c7126bb418410acbef6c81Lennart Poettering
16e9f408fa9a9626059bdd6c89dc175e06b9e976Lennart Poettering break;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering }
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering }
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering if (!valid)
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Locale data.");
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering }
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering /* Check whether a variable is unset */
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering if (!modified)
5e41cfec83aa47af12e469bc62e336f8213ee066Lennart Poettering for (p = 0; p < _LOCALE_MAX; p++)
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering if (!isempty(c->locale[p]) && !passed[p]) {
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering modified = true;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering break;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering }
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering if (modified) {
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering _cleanup_strv_free_ char **settings = NULL;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-locale", interactive, &c->polkit_registry, error);
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering if (r < 0)
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering return r;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering if (r == 0)
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering
205c4d1d6a3f5343f970abf20283d69dcec359edLennart Poettering STRV_FOREACH(i, l)
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering for (p = 0; p < _LOCALE_MAX; p++) {
e156d769c3ee756cdb20f8522ace9ea459a82655Lennart Poettering size_t k;
54a7b863dd3937893abae47b20b6f655b8e9252aLennart Poettering
54a7b863dd3937893abae47b20b6f655b8e9252aLennart Poettering k = strlen(names[p]);
54a7b863dd3937893abae47b20b6f655b8e9252aLennart Poettering if (startswith(*i, names[p]) && (*i)[k] == '=') {
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering r = free_and_strdup(&c->locale[p], *i + k + 1);
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering if (r < 0)
54a7b863dd3937893abae47b20b6f655b8e9252aLennart Poettering return r;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering break;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering }
6c1e6b98bde8288d65d7cddf87ff9bedf94a3e1cLennart Poettering }
6c1e6b98bde8288d65d7cddf87ff9bedf94a3e1cLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering for (p = 0; p < _LOCALE_MAX; p++) {
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering if (passed[p])
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering continue;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering free_and_replace(&c->locale[p], NULL);
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering }
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering locale_simplify(c);
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering r = locale_write_data(c, &settings);
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering if (r < 0) {
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering log_error("Failed to set locale: %s", strerror(-r));
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering return sd_bus_error_set_errnof(error, r, "Failed to set locale: %s", strerror(-r));
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering }
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering locale_update_system_manager(c, bus);
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering if (settings) {
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering _cleanup_free_ char *line;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering line = strv_join(settings, ", ");
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering log_info("Changed locale to %s.", strnull(line));
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering } else
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering log_info("Changed locale to unset.");
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering sd_bus_emit_properties_changed(bus,
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering "/org/freedesktop/locale1",
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering "org.freedesktop.locale1",
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering "Locale", NULL);
b1a0ab714863ae77e4683820757b3f49c03a0049Lennart Poettering } else
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering log_debug("Locale settings were not modified.");
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering return sd_bus_reply_method_return(m, NULL);
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering}
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poetteringstatic int method_set_vc_keyboard(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering Context *c = userdata;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering const char *keymap, *keymap_toggle;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering int convert, interactive;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering int r;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering r = sd_bus_message_read(m, "ssbb", &keymap, &keymap_toggle, &convert, &interactive);
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering if (r < 0)
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering return r;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering if (isempty(keymap))
4a299a7ad547becb70e8271eaf8cdc27e8e6836aLennart Poettering keymap = NULL;
4a299a7ad547becb70e8271eaf8cdc27e8e6836aLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering if (isempty(keymap_toggle))
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering keymap_toggle = NULL;
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering if (!streq_ptr(keymap, c->vc_keymap) ||
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering !streq_ptr(keymap_toggle, c->vc_keymap_toggle)) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
ba6b3039531a70466dd955c6faa9bf521b3dfbacLennart Poettering if ((keymap && (!filename_is_safe(keymap) || !string_is_safe(keymap))) ||
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering (keymap_toggle && (!filename_is_safe(keymap_toggle) || !string_is_safe(keymap_toggle))))
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return sd_bus_error_set_errnof(error, -EINVAL, "Received invalid keymap data");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-keyboard", interactive, &c->polkit_registry, error);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return r;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (r == 0)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (free_and_strdup(&c->vc_keymap, keymap) < 0 ||
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering free_and_strdup(&c->vc_keymap_toggle, keymap_toggle) < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -ENOMEM;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = vconsole_write_data(c);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Failed to set virtual console keymap: %s", strerror(-r));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return sd_bus_error_set_errnof(error, r, "Failed to set virtual console keymap: %s", strerror(-r));
6c1e6b98bde8288d65d7cddf87ff9bedf94a3e1cLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_info("Changed virtual console keymap to '%s' toggle '%s'",
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering strempty(c->vc_keymap), strempty(c->vc_keymap_toggle));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
3146a302d184d64a5c75237129f9e4f54ce46cd3Lennart Poettering r = vconsole_reload(bus);
3146a302d184d64a5c75237129f9e4f54ce46cd3Lennart Poettering if (r < 0)
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering log_error("Failed to request keymap reload: %s", strerror(-r));
b8156be03f71c53072c7126bb418410acbef6c81Lennart Poettering
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering sd_bus_emit_properties_changed(bus,
ba6b3039531a70466dd955c6faa9bf521b3dfbacLennart Poettering "/org/freedesktop/locale1",
ba6b3039531a70466dd955c6faa9bf521b3dfbacLennart Poettering "org.freedesktop.locale1",
ba6b3039531a70466dd955c6faa9bf521b3dfbacLennart Poettering "VConsoleKeymap", "VConsoleKeymapToggle", NULL);
ba6b3039531a70466dd955c6faa9bf521b3dfbacLennart Poettering
ba6b3039531a70466dd955c6faa9bf521b3dfbacLennart Poettering if (convert) {
ba6b3039531a70466dd955c6faa9bf521b3dfbacLennart Poettering r = vconsole_convert_to_x11(c, bus);
ba6b3039531a70466dd955c6faa9bf521b3dfbacLennart Poettering if (r < 0)
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering log_error("Failed to convert keymap data: %s", strerror(-r));
cf244689e9d1ab50082c9ddd0f3c4d1eb982badcLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
51abe64c859c01ffad4f80840396ad9f6d5c9e62Lennart Poettering return sd_bus_reply_method_return(m, NULL);
6c1e6b98bde8288d65d7cddf87ff9bedf94a3e1cLennart Poettering}
6c1e6b98bde8288d65d7cddf87ff9bedf94a3e1cLennart Poettering
6c1e6b98bde8288d65d7cddf87ff9bedf94a3e1cLennart Poetteringstatic int method_set_x11_keyboard(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
6c1e6b98bde8288d65d7cddf87ff9bedf94a3e1cLennart Poettering Context *c = userdata;
6c1e6b98bde8288d65d7cddf87ff9bedf94a3e1cLennart Poettering const char *layout, *model, *variant, *options;
6c1e6b98bde8288d65d7cddf87ff9bedf94a3e1cLennart Poettering int convert, interactive;
6c1e6b98bde8288d65d7cddf87ff9bedf94a3e1cLennart Poettering int r;
51abe64c859c01ffad4f80840396ad9f6d5c9e62Lennart Poettering
6c1e6b98bde8288d65d7cddf87ff9bedf94a3e1cLennart Poettering r = sd_bus_message_read(m, "ssssbb", &layout, &model, &variant, &options, &convert, &interactive);
6c1e6b98bde8288d65d7cddf87ff9bedf94a3e1cLennart Poettering if (r < 0)
6c1e6b98bde8288d65d7cddf87ff9bedf94a3e1cLennart Poettering return r;
6c1e6b98bde8288d65d7cddf87ff9bedf94a3e1cLennart Poettering
6c1e6b98bde8288d65d7cddf87ff9bedf94a3e1cLennart Poettering if (isempty(layout))
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering layout = NULL;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (isempty(model))
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering model = NULL;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (isempty(variant))
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering variant = NULL;
cec736d21ff86c4ac81b4d306ddba2120333818cLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (isempty(options))
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering options = NULL;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (!streq_ptr(layout, c->x11_layout) ||
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering !streq_ptr(model, c->x11_model) ||
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering !streq_ptr(variant, c->x11_variant) ||
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering !streq_ptr(options, c->x11_options)) {
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if ((layout && !string_is_safe(layout)) ||
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (model && !string_is_safe(model)) ||
7264278fbbdc1dc6c30fedc902d1337594aa6ff6Lennart Poettering (variant && !string_is_safe(variant)) ||
7264278fbbdc1dc6c30fedc902d1337594aa6ff6Lennart Poettering (options && !string_is_safe(options)))
7264278fbbdc1dc6c30fedc902d1337594aa6ff6Lennart Poettering return sd_bus_error_set_errnof(error, -EINVAL, "Received invalid keyboard data");
7264278fbbdc1dc6c30fedc902d1337594aa6ff6Lennart Poettering
7264278fbbdc1dc6c30fedc902d1337594aa6ff6Lennart Poettering r = bus_verify_polkit_async(m, CAP_SYS_ADMIN, "org.freedesktop.locale1.set-keyboard", interactive, &c->polkit_registry, error);
7264278fbbdc1dc6c30fedc902d1337594aa6ff6Lennart Poettering if (r < 0)
7264278fbbdc1dc6c30fedc902d1337594aa6ff6Lennart Poettering return r;
7264278fbbdc1dc6c30fedc902d1337594aa6ff6Lennart Poettering if (r == 0)
7264278fbbdc1dc6c30fedc902d1337594aa6ff6Lennart Poettering return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
7264278fbbdc1dc6c30fedc902d1337594aa6ff6Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (free_and_strdup(&c->x11_layout, layout) < 0 ||
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering free_and_strdup(&c->x11_model, model) < 0 ||
7264278fbbdc1dc6c30fedc902d1337594aa6ff6Lennart Poettering free_and_strdup(&c->x11_variant, variant) < 0 ||
7264278fbbdc1dc6c30fedc902d1337594aa6ff6Lennart Poettering free_and_strdup(&c->x11_options, options) < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -ENOMEM;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = write_data_x11(c);
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering if (r < 0) {
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering log_error("Failed to set X11 keyboard layout: %s", strerror(-r));
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return sd_bus_error_set_errnof(error, r, "Failed to set X11 keyboard layout: %s", strerror(-r));
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering log_info("Changed X11 keyboard layout to '%s' model '%s' variant '%s' options '%s'",
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering strempty(c->x11_layout),
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering strempty(c->x11_model),
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering strempty(c->x11_variant),
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering strempty(c->x11_options));
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering sd_bus_emit_properties_changed(bus,
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering "/org/freedesktop/locale1",
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering "org.freedesktop.locale1",
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering "X11Layout", "X11Model", "X11Variant", "X11Options", NULL);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (convert) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = x11_convert_to_vconsole(c, bus);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (r < 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering log_error("Failed to convert keymap data: %s", strerror(-r));
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return sd_bus_reply_method_return(m, NULL);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringstatic const sd_bus_vtable locale_vtable[] = {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering SD_BUS_VTABLE_START(0),
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering SD_BUS_PROPERTY("Locale", "as", property_get_locale, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering SD_BUS_PROPERTY("X11Layout", "s", NULL, offsetof(Context, x11_layout), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering SD_BUS_PROPERTY("X11Model", "s", NULL, offsetof(Context, x11_model), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering SD_BUS_PROPERTY("X11Variant", "s", NULL, offsetof(Context, x11_variant), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering SD_BUS_PROPERTY("X11Options", "s", NULL, offsetof(Context, x11_options), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering SD_BUS_PROPERTY("VConsoleKeymap", "s", NULL, offsetof(Context, vc_keymap), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering SD_BUS_PROPERTY("VConsoleKeymapToggle", "s", NULL, offsetof(Context, vc_keymap_toggle), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering SD_BUS_METHOD("SetLocale", "asb", NULL, method_set_locale, SD_BUS_VTABLE_UNPRIVILEGED),
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering SD_BUS_METHOD("SetVConsoleKeyboard", "ssbb", NULL, method_set_vc_keyboard, SD_BUS_VTABLE_UNPRIVILEGED),
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering SD_BUS_METHOD("SetX11Keyboard", "ssssbb", NULL, method_set_x11_keyboard, SD_BUS_VTABLE_UNPRIVILEGED),
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering SD_BUS_VTABLE_END
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering};
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering _cleanup_bus_close_unref_ sd_bus *bus = NULL;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(c);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(event);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(_bus);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = sd_bus_default_system(&bus);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Failed to get system bus connection: %s", strerror(-r));
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering return r;
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering }
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering
7f2c63cbf47c89ec56f50469f6551df473dd65d8Lennart Poettering r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/locale1", "org.freedesktop.locale1", locale_vtable, c);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Failed to register object: %s", strerror(-r));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering }
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering r = sd_bus_request_name(bus, "org.freedesktop.locale1", 0);
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering if (r < 0) {
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering log_error("Failed to register name: %s", strerror(-r));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = sd_bus_attach_event(bus, event, 0);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (r < 0) {
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering log_error("Failed to attach bus to event loop: %s", strerror(-r));
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering return r;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering }
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering *_bus = bus;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering bus = NULL;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering return 0;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering}
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poetteringint main(int argc, char *argv[]) {
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering _cleanup_(context_free) Context context = {};
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering _cleanup_event_unref_ sd_event *event = NULL;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering _cleanup_bus_close_unref_ sd_bus *bus = NULL;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering int r;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering log_set_target(LOG_TARGET_AUTO);
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering log_parse_environment();
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering log_open();
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering umask(0022);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering label_init("/etc");
cec736d21ff86c4ac81b4d306ddba2120333818cLennart Poettering
cec736d21ff86c4ac81b4d306ddba2120333818cLennart Poettering if (argc != 1) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("This program takes no arguments.");
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering r = -EINVAL;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering goto finish;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering r = sd_event_default(&event);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (r < 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("Failed to allocate event loop: %s", strerror(-r));
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering goto finish;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering sd_event_set_watchdog(event, true);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering r = connect_bus(&context, event, &bus);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (r < 0)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering goto finish;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering r = context_read_data(&context);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (r < 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("Failed to read locale data: %s", strerror(-r));
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering goto finish;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering r = bus_event_loop_with_idle(event, bus, "org.freedesktop.locale1", DEFAULT_EXIT_USEC, NULL, NULL);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (r < 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering log_error("Failed to run event loop: %s", strerror(-r));
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering goto finish;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poetteringfinish:
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering}
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering