2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering/***
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering This file is part of systemd.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering Copyright 2012 Lennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers Copyright 2013 Kay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering systemd is free software; you can redistribute it and/or modify it
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering under the terms of the GNU Lesser General Public License as published by
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering (at your option) any later version.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering systemd is distributed in the hope that it will be useful, but
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering Lesser General Public License for more details.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering You should have received a copy of the GNU Lesser General Public License
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering***/
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include <ftw.h>
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include <getopt.h>
a9cdc94f7ff40f22a3cf9472f612a80730a1b010Dave Reisner#include <locale.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <stdbool.h>
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include <stdlib.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <string.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers#include "sd-bus.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers#include "bus-error.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "bus-util.h"
0732ef7acf37473847992888bcb6446726d9d877Zbigniew Jędrzejewski-Szmek#include "def.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "fd-util.h"
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar#include "fileio.h"
7568345034f2890af745747783c5abfbf6eccf0fLennart Poettering#include "locale-util.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "pager.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "set.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "spawn-polkit-agent.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "strv.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "util.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "virt.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic bool arg_no_pager = false;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic bool arg_ask_password = true;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sieversstatic BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
7085053a437456ab87d726f3697002dd811fdf7aDaniel Wallacestatic char *arg_host = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic bool arg_convert = true;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic void pager_open_if_enabled(void) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (arg_no_pager)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
1b12a7b5896f94bdf33b3a6661ebabd761ea6adcHarald Hoyer pager_open(false);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic void polkit_agent_open_if_enabled(void) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* Open the polkit agent as a child process if necessary */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!arg_ask_password)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering if (arg_transport != BUS_TRANSPORT_LOCAL)
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering return;
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering polkit_agent_open();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringtypedef struct StatusInfo {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char **locale;
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann char *vconsole_keymap;
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann char *vconsole_keymap_toggle;
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann char *x11_layout;
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann char *x11_model;
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann char *x11_variant;
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann char *x11_options;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering} StatusInfo;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmannstatic void status_info_clear(StatusInfo *info) {
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann if (info) {
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann strv_free(info->locale);
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann free(info->vconsole_keymap);
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann free(info->vconsole_keymap_toggle);
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann free(info->x11_layout);
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann free(info->x11_model);
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann free(info->x11_variant);
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann free(info->x11_options);
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann zero(*info);
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann }
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann}
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann
ff9b60f38bf68eba4a47cabff14547d92e083214Torstein Husebøstatic void print_overridden_variables(void) {
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar int r;
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar char *variables[_VARIABLE_LC_MAX] = {};
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar LocaleVariable j;
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar bool print_warning = true;
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar
75f86906c52735c98dc0aa7e24b773edb42ee814Lennart Poettering if (detect_container() > 0 || arg_host)
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar return;
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar r = parse_env_file("/proc/cmdline", WHITESPACE,
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar "locale.LANG", &variables[VARIABLE_LANG],
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar "locale.LANGUAGE", &variables[VARIABLE_LANGUAGE],
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar "locale.LC_CTYPE", &variables[VARIABLE_LC_CTYPE],
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar "locale.LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC],
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar "locale.LC_TIME", &variables[VARIABLE_LC_TIME],
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar "locale.LC_COLLATE", &variables[VARIABLE_LC_COLLATE],
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar "locale.LC_MONETARY", &variables[VARIABLE_LC_MONETARY],
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar "locale.LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES],
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar "locale.LC_PAPER", &variables[VARIABLE_LC_PAPER],
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar "locale.LC_NAME", &variables[VARIABLE_LC_NAME],
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar "locale.LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS],
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar "locale.LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE],
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar "locale.LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT],
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar "locale.LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar NULL);
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar if (r < 0 && r != -ENOENT) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_warning_errno(r, "Failed to read /proc/cmdline: %m");
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar goto finish;
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar }
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar
63229aa1abdb98aa69fda9819ed2f40c8082762bLennart Poettering for (j = 0; j < _VARIABLE_LC_MAX; j++)
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar if (variables[j]) {
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar if (print_warning) {
b344bcbbfda8fbe14dadc5aa4b5dfb3ced6d76e2Lennart Poettering log_warning("Warning: Settings on kernel command line override system locale settings in /etc/locale.conf.\n"
ff49bc3212cb07d850dcfd59940539773a0be26fMichal Schmidt " Command Line: %s=%s", locale_variable_to_string(j), variables[j]);
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar print_warning = false;
b344bcbbfda8fbe14dadc5aa4b5dfb3ced6d76e2Lennart Poettering } else
ff49bc3212cb07d850dcfd59940539773a0be26fMichal Schmidt log_warning(" %s=%s", locale_variable_to_string(j), variables[j]);
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar }
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar finish:
63229aa1abdb98aa69fda9819ed2f40c8082762bLennart Poettering for (j = 0; j < _VARIABLE_LC_MAX; j++)
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar free(variables[j]);
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar}
a34286684ebb78dd3db0d7f34feb2c121c9d00ccMichal Sekletar
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic void print_status_info(StatusInfo *i) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(i);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (strv_isempty(i->locale))
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering puts(" System Locale: n/a\n");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char **j;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering printf(" System Locale: %s\n", i->locale[0]);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering STRV_FOREACH(j, i->locale + 1)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering printf(" %s\n", *j);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering printf(" VC Keymap: %s\n", strna(i->vconsole_keymap));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!isempty(i->vconsole_keymap_toggle))
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering printf("VC Toggle Keymap: %s\n", i->vconsole_keymap_toggle);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering printf(" X11 Layout: %s\n", strna(i->x11_layout));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!isempty(i->x11_model))
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering printf(" X11 Model: %s\n", i->x11_model);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!isempty(i->x11_variant))
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering printf(" X11 Variant: %s\n", i->x11_variant);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!isempty(i->x11_options))
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering printf(" X11 Options: %s\n", i->x11_options);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sieversstatic int show_status(sd_bus *bus, char **args, unsigned n) {
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann _cleanup_(status_info_clear) StatusInfo info = {};
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers static const struct bus_properties_map map[] = {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers { "VConsoleKeymap", "s", NULL, offsetof(StatusInfo, vconsole_keymap) },
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers { "VConsoleKeymap", "s", NULL, offsetof(StatusInfo, vconsole_keymap) },
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers { "VConsoleKeymapToggle", "s", NULL, offsetof(StatusInfo, vconsole_keymap_toggle) },
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers { "X11Layout", "s", NULL, offsetof(StatusInfo, x11_layout) },
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers { "X11Model", "s", NULL, offsetof(StatusInfo, x11_model) },
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers { "X11Variant", "s", NULL, offsetof(StatusInfo, x11_variant) },
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers { "X11Options", "s", NULL, offsetof(StatusInfo, x11_options) },
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers { "Locale", "as", NULL, offsetof(StatusInfo, locale) },
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers {}
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers };
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers assert(bus);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers r = bus_map_all_properties(bus,
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers "org.freedesktop.locale1",
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers "/org/freedesktop/locale1",
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers map,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers &info);
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann if (r < 0)
e7e55dbdc38f929805ab2407fbd50886043a9e7cDavid Herrmann return log_error_errno(r, "Could not get properties: %m");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
ff9b60f38bf68eba4a47cabff14547d92e083214Torstein Husebø print_overridden_variables();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering print_status_info(&info);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers return r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sieversstatic int set_locale(sd_bus *bus, char **args, unsigned n) {
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(bus);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(args);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering polkit_agent_open_if_enabled();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering r = sd_bus_message_new_method_call(
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering bus,
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering &m,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "org.freedesktop.locale1",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "/org/freedesktop/locale1",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "org.freedesktop.locale1",
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering "SetLocale");
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers if (r < 0)
94676f3e9352cbf1f72e0a512ee0d2ed83ff676dLennart Poettering return bus_log_create_error(r);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers r = sd_bus_message_append_strv(m, args + 1);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers if (r < 0)
94676f3e9352cbf1f72e0a512ee0d2ed83ff676dLennart Poettering return bus_log_create_error(r);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers r = sd_bus_message_append(m, "b", arg_ask_password);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
94676f3e9352cbf1f72e0a512ee0d2ed83ff676dLennart Poettering return bus_log_create_error(r);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
c49b30a23583ff39daaa26696bcab478d2fee0bbLennart Poettering r = sd_bus_call(bus, m, 0, &error, NULL);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers if (r < 0) {
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers return r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sieversstatic int list_locales(sd_bus *bus, char **args, unsigned n) {
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna _cleanup_strv_free_ char **l = NULL;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna int r;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
7568345034f2890af745747783c5abfbf6eccf0fLennart Poettering assert(args);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
7568345034f2890af745747783c5abfbf6eccf0fLennart Poettering r = get_locales(&l);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (r < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Failed to read list of locales: %m");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering pager_open_if_enabled();
7c2d80944afb4196f2eff614e8da1450dffcbeaaThomas Hindoe Paaboel Andersen strv_print(l);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sieversstatic int set_vconsole_keymap(sd_bus *bus, char **args, unsigned n) {
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *map, *toggle_map;
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(bus);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(args);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (n > 3) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("Too many arguments.");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -EINVAL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering polkit_agent_open_if_enabled();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering map = args[1];
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering toggle_map = n > 2 ? args[2] : "";
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering r = sd_bus_call_method(
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering bus,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "org.freedesktop.locale1",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "/org/freedesktop/locale1",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "org.freedesktop.locale1",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "SetVConsoleKeyboard",
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers &error,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering NULL,
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers "ssbb", map, toggle_map, arg_convert, arg_ask_password);
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering if (r < 0)
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering log_error("Failed to set keymap: %s", bus_error_message(&error, -r));
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering return r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic Set *keymaps = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic int nftw_cb(
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *fpath,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const struct stat *sb,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int tflag,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering struct FTW *ftwbuf) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char *p, *e;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (tflag != FTW_F)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!endswith(fpath, ".map") &&
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering !endswith(fpath, ".map.gz"))
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2b6bf07dd23bb467099d213c97b3875c5e453491Zbigniew Jędrzejewski-Szmek p = strdup(basename(fpath));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!p)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return log_oom();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering e = endswith(p, ".map");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (e)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *e = 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering e = endswith(p, ".map.gz");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (e)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *e = 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmek r = set_consume(keymaps, p);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (r < 0 && r != -EEXIST)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Can't add keymap: %m");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sieversstatic int list_vconsole_keymaps(sd_bus *bus, char **args, unsigned n) {
7fd1b19bc9e9f5574f2877936b8ac267c7706947Harald Hoyer _cleanup_strv_free_ char **l = NULL;
0732ef7acf37473847992888bcb6446726d9d877Zbigniew Jędrzejewski-Szmek const char *dir;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt keymaps = set_new(&string_hash_ops);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!keymaps)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return log_oom();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
0732ef7acf37473847992888bcb6446726d9d877Zbigniew Jędrzejewski-Szmek NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS)
0732ef7acf37473847992888bcb6446726d9d877Zbigniew Jędrzejewski-Szmek nftw(dir, nftw_cb, 20, FTW_MOUNT|FTW_PHYS);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering l = set_get_strv(keymaps);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!l) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering set_free_free(keymaps);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return log_oom();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering set_free(keymaps);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (strv_isempty(l)) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("Couldn't find any console keymaps.");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -ENOENT;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering strv_sort(l);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering pager_open_if_enabled();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
7c2d80944afb4196f2eff614e8da1450dffcbeaaThomas Hindoe Paaboel Andersen strv_print(l);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sieversstatic int set_x11_keymap(sd_bus *bus, char **args, unsigned n) {
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *layout, *model, *variant, *options;
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(bus);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(args);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (n > 5) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("Too many arguments.");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -EINVAL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering polkit_agent_open_if_enabled();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering layout = args[1];
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering model = n > 2 ? args[2] : "";
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering variant = n > 3 ? args[3] : "";
6b2b6f30e38d67b032d6bdc6b47ae05e143e96c5Michal Schmidt options = n > 4 ? args[4] : "";
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering r = sd_bus_call_method(
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering bus,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "org.freedesktop.locale1",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "/org/freedesktop/locale1",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "org.freedesktop.locale1",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "SetX11Keyboard",
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers &error,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering NULL,
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers "ssssbb", layout, model, variant, options,
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers arg_convert, arg_ask_password);
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering if (r < 0)
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering log_error("Failed to set keymap: %s", bus_error_message(&error, -r));
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering return r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sieversstatic int list_x11_keymaps(sd_bus *bus, char **args, unsigned n) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
7fd1b19bc9e9f5574f2877936b8ac267c7706947Harald Hoyer _cleanup_strv_free_ char **list = NULL;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering char line[LINE_MAX];
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering enum {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering NONE,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering MODELS,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering LAYOUTS,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering VARIANTS,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering OPTIONS
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering } state = NONE, look_for;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering int r;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (n > 2) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering log_error("Too many arguments.");
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering return -EINVAL;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
c62e11ce3966c55d23520b9f0785c7e839cf7f37Lennart Poettering f = fopen("/usr/share/X11/xkb/rules/base.lst", "re");
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt if (!f)
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_error_errno(errno, "Failed to open keyboard mapping list. %m");
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (streq(args[0], "list-x11-keymap-models"))
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering look_for = MODELS;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering else if (streq(args[0], "list-x11-keymap-layouts"))
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering look_for = LAYOUTS;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering else if (streq(args[0], "list-x11-keymap-variants"))
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering look_for = VARIANTS;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering else if (streq(args[0], "list-x11-keymap-options"))
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering look_for = OPTIONS;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering else
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering assert_not_reached("Wrong parameter");
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering FOREACH_LINE(line, f, break) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering char *l, *w;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering l = strstrip(line);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (isempty(l))
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering continue;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (l[0] == '!') {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (startswith(l, "! model"))
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering state = MODELS;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering else if (startswith(l, "! layout"))
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering state = LAYOUTS;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering else if (startswith(l, "! variant"))
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering state = VARIANTS;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering else if (startswith(l, "! option"))
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering state = OPTIONS;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering else
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering state = NONE;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering continue;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (state != look_for)
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering continue;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering w = l + strcspn(l, WHITESPACE);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (n > 1) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering char *e;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (*w == 0)
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering continue;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering *w = 0;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering w++;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering w += strspn(w, WHITESPACE);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering e = strchr(w, ':');
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (!e)
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering continue;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering *e = 0;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (!streq(w, args[1]))
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering continue;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering } else
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering *w = 0;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
7d6884b65e6ea7317346d29bc2f6c9ba051a0cacThomas Hindoe Paaboel Andersen r = strv_extend(&list, l);
7d6884b65e6ea7317346d29bc2f6c9ba051a0cacThomas Hindoe Paaboel Andersen if (r < 0)
7d6884b65e6ea7317346d29bc2f6c9ba051a0cacThomas Hindoe Paaboel Andersen return log_oom();
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (strv_isempty(list)) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering log_error("Couldn't find any entries.");
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering return -ENOENT;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering strv_sort(list);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering strv_uniq(list);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering pager_open_if_enabled();
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering strv_print(list);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering return 0;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering}
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmekstatic void help(void) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering printf("%s [OPTIONS...] COMMAND ...\n\n"
82c1d8f4eb74ddd9be2c9b9b56d9dc564c599effLennart Poettering "Query or change system locale and keyboard settings.\n\n"
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering " -h --help Show this help\n"
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering " --version Show package version\n"
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering " --no-pager Do not pipe output into a pager\n"
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering " --no-ask-password Do not prompt for password\n"
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers " -H --host=[USER@]HOST Operate on remote host\n"
a86a47ce1f63476631635fbcbc10af8877172114Lennart Poettering " -M --machine=CONTAINER Operate on local container\n"
a86a47ce1f63476631635fbcbc10af8877172114Lennart Poettering " --no-convert Don't convert keyboard mappings\n\n"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "Commands:\n"
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering " status Show current locale settings\n"
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering " set-locale LOCALE... Set system locale\n"
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering " list-locales Show known locales\n"
2ebcf936702e8e511098711b4add885372360018Zbigniew Jędrzejewski-Szmek " set-keymap MAP [MAP] Set console and X11 keyboard mappings\n"
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering " list-keymaps Show known virtual console keyboard mappings\n"
31cf921abbeafc9dae2d5c777f3e2285e6f4c19dJan Synacek " set-x11-keymap LAYOUT [MODEL [VARIANT [OPTIONS]]]\n"
2ebcf936702e8e511098711b4add885372360018Zbigniew Jędrzejewski-Szmek " Set X11 and console keyboard mappings\n"
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering " list-x11-keymap-models Show known X11 keyboard mapping models\n"
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering " list-x11-keymap-layouts Show known X11 keyboard mapping layouts\n"
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering " list-x11-keymap-variants [LAYOUT]\n"
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering " Show known X11 keyboard mapping variants\n"
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek " list-x11-keymap-options Show known X11 keyboard mapping options\n"
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek , program_invocation_short_name);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic int parse_argv(int argc, char *argv[]) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering enum {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ARG_VERSION = 0x100,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ARG_NO_PAGER,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ARG_NO_CONVERT,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ARG_NO_ASK_PASSWORD
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering };
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering static const struct option options[] = {
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers { "help", no_argument, NULL, 'h' },
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers { "version", no_argument, NULL, ARG_VERSION },
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers { "no-pager", no_argument, NULL, ARG_NO_PAGER },
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers { "host", required_argument, NULL, 'H' },
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers { "machine", required_argument, NULL, 'M' },
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers { "no-convert", no_argument, NULL, ARG_NO_CONVERT },
eb9da376d76b48585b3b63b4f91903b54f7abd36Lennart Poettering {}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering };
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int c;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(argc >= 0);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(argv);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek while ((c = getopt_long(argc, argv, "hH:M:", options, NULL)) >= 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering switch (c) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering case 'h':
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek help();
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering case ARG_VERSION:
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering return version();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering case ARG_NO_CONVERT:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering arg_convert = false;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering case ARG_NO_PAGER:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering arg_no_pager = true;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
546158bc6f46f8004cc11e81d19d223e0da56730Jan Janssen case ARG_NO_ASK_PASSWORD:
546158bc6f46f8004cc11e81d19d223e0da56730Jan Janssen arg_ask_password = false;
546158bc6f46f8004cc11e81d19d223e0da56730Jan Janssen break;
546158bc6f46f8004cc11e81d19d223e0da56730Jan Janssen
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers case 'H':
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers arg_transport = BUS_TRANSPORT_REMOTE;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers arg_host = optarg;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers break;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers case 'M':
de33fc625725d199629ed074d6278504deb23debLennart Poettering arg_transport = BUS_TRANSPORT_MACHINE;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers arg_host = optarg;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers break;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering case '?':
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -EINVAL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering default:
eb9da376d76b48585b3b63b4f91903b54f7abd36Lennart Poettering assert_not_reached("Unhandled option");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 1;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sieversstatic int localectl_main(sd_bus *bus, int argc, char *argv[]) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering static const struct {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char* verb;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const enum {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering MORE,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering LESS,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering EQUAL
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering } argc_cmp;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const int argc;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers int (* const dispatch)(sd_bus *bus, char **args, unsigned n);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering } verbs[] = {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering { "status", LESS, 1, show_status },
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering { "set-locale", MORE, 2, set_locale },
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering { "list-locales", EQUAL, 1, list_locales },
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering { "set-keymap", MORE, 2, set_vconsole_keymap },
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering { "list-keymaps", EQUAL, 1, list_vconsole_keymaps },
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering { "set-x11-keymap", MORE, 2, set_x11_keymap },
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering { "list-x11-keymap-models", EQUAL, 1, list_x11_keymaps },
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering { "list-x11-keymap-layouts", EQUAL, 1, list_x11_keymaps },
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering { "list-x11-keymap-variants", LESS, 2, list_x11_keymaps },
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering { "list-x11-keymap-options", EQUAL, 1, list_x11_keymaps },
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering };
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int left;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering unsigned i;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(argc >= 0);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(argv);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering left = argc - optind;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (left <= 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* Special rule: no arguments means "status" */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering i = 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (streq(argv[optind], "help")) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering help();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering for (i = 0; i < ELEMENTSOF(verbs); i++)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (streq(argv[optind], verbs[i].verb))
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (i >= ELEMENTSOF(verbs)) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("Unknown operation %s", argv[optind]);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -EINVAL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering switch (verbs[i].argc_cmp) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering case EQUAL:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (left != verbs[i].argc) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("Invalid number of arguments.");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -EINVAL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering case MORE:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (left < verbs[i].argc) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("Too few arguments.");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -EINVAL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering case LESS:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (left > verbs[i].argc) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("Too many arguments.");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -EINVAL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering default:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert_not_reached("Unknown comparison operator.");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return verbs[i].dispatch(bus, argv + optind, left);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sieversint main(int argc, char*argv[]) {
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
a9cdc94f7ff40f22a3cf9472f612a80730a1b010Dave Reisner setlocale(LC_ALL, "");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_parse_environment();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_open();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = parse_argv(argc, argv);
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering if (r <= 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering goto finish;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
266f3e269d173f104aa2a5e3ceac9b6979ea5039Lennart Poettering r = bus_connect_transport(arg_transport, arg_host, false, &bus);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers if (r < 0) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_error_errno(r, "Failed to create bus connection: %m");
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers goto finish;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers r = localectl_main(bus, argc, argv);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sieversfinish:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering pager_close();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}