localectl.c revision 6b2b6f30e38d67b032d6bdc6b47ae05e143e96c5
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer/***
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer This file is part of systemd.
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer Copyright 2012 Lennart Poettering
0fe15dc8ddddeb39a5cad1f4f4afa25fa074a5d1Evgeny Vereshchagin
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer systemd is free software; you can redistribute it and/or modify it
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer under the terms of the GNU Lesser General Public License as published by
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer the Free Software Foundation; either version 2.1 of the License, or
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt (at your option) any later version.
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt systemd is distributed in the hope that it will be useful, but
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt WITHOUT ANY WARRANTY; without even the implied warranty of
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4be4833ece2856e0cacc09f8f8b2c02b320751faMartin Pitt Lesser General Public License for more details.
c50a4525aa8151b180d5a325e88c5f3812e66c36Martin Pitt
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier You should have received a copy of the GNU Lesser General Public License
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier along with systemd; If not, see <http://www.gnu.org/licenses/>.
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier***/
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <locale.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <stdlib.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <stdbool.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <unistd.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <getopt.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <string.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <ftw.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <sys/mman.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <fcntl.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "dbus-common.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "util.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "spawn-polkit-agent.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "build.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "strv.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "pager.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "set.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "path-util.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalierstatic bool arg_no_pager = false;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalierstatic enum transport {
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier TRANSPORT_NORMAL,
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier TRANSPORT_SSH,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier TRANSPORT_POLKIT
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyer} arg_transport = TRANSPORT_NORMAL;
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyerstatic bool arg_ask_password = true;
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyerstatic const char *arg_host = NULL;
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyerstatic bool arg_convert = true;
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyer
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyerstatic void pager_open_if_enabled(void) {
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyer
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyer if (arg_no_pager)
61fea35e14d84144e6e2122f5cd247f9c7e6245eEvgeny Vereshchagin return;
61fea35e14d84144e6e2122f5cd247f9c7e6245eEvgeny Vereshchagin
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier pager_open();
61fea35e14d84144e6e2122f5cd247f9c7e6245eEvgeny Vereshchagin}
61fea35e14d84144e6e2122f5cd247f9c7e6245eEvgeny Vereshchagin
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalierstatic void polkit_agent_open_if_enabled(void) {
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier /* Open the polkit agent as a child process if necessary */
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier if (!arg_ask_password)
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier return;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier polkit_agent_open();
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt}
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevaliertypedef struct StatusInfo {
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier char **locale;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier const char *vconsole_keymap;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier const char *vconsole_keymap_toggle;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier const char *x11_layout;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier const char *x11_model;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier const char *x11_variant;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier const char *x11_options;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier} StatusInfo;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalierstatic void print_status_info(StatusInfo *i) {
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier assert(i);
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier if (strv_isempty(i->locale))
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier puts(" System Locale: n/a\n");
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier else {
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier char **j;
8a8332f77e61d41f3bb28b8f929ed41e0ffaf721Zbigniew Jędrzejewski-Szmek
8a8332f77e61d41f3bb28b8f929ed41e0ffaf721Zbigniew Jędrzejewski-Szmek printf(" System Locale: %s\n", i->locale[0]);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier STRV_FOREACH(j, i->locale + 1)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier printf(" %s\n", *j);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
8a8332f77e61d41f3bb28b8f929ed41e0ffaf721Zbigniew Jędrzejewski-Szmek
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt printf(" VC Keymap: %s\n", strna(i->vconsole_keymap));
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!isempty(i->vconsole_keymap_toggle))
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier printf("VC Toggle Keymap: %s\n", i->vconsole_keymap_toggle);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier printf(" X11 Layout: %s\n", strna(i->x11_layout));
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!isempty(i->x11_model))
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier printf(" X11 Model: %s\n", i->x11_model);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!isempty(i->x11_variant))
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier printf(" X11 Variant: %s\n", i->x11_variant);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!isempty(i->x11_options))
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier printf(" X11 Options: %s\n", i->x11_options);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier}
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic int status_property(const char *name, DBusMessageIter *iter, StatusInfo *i) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier int r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert(name);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert(iter);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier switch (dbus_message_iter_get_arg_type(iter)) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier case DBUS_TYPE_STRING: {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier const char *s;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier dbus_message_iter_get_basic(iter, &s);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!isempty(s)) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (streq(name, "VConsoleKeymap"))
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier i->vconsole_keymap = s;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier else if (streq(name, "VConsoleKeymapToggle"))
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier i->vconsole_keymap_toggle = s;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier else if (streq(name, "X11Layout"))
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier i->x11_layout = s;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier else if (streq(name, "X11Model"))
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier i->x11_model = s;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier else if (streq(name, "X11Variant"))
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier i->x11_variant = s;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier else if (streq(name, "X11Options"))
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier i->x11_options = s;
8a8332f77e61d41f3bb28b8f929ed41e0ffaf721Zbigniew Jędrzejewski-Szmek }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier break;
2375607039517c88df51ef16ddbb624ec1c10654Kay Sievers }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier case DBUS_TYPE_ARRAY:
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier char **l;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = bus_parse_strv_iter(iter, &l);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (streq(name, "Locale")) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier strv_free(i->locale);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier i->locale = l;
739d81ddd005fae2bb82edce5b8a6173c7c48b34Zbigniew Jędrzejewski-Szmek l = NULL;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
b8667ee4162cd2510363602b417cecede9fd2ccaZbigniew Jędrzejewski-Szmek
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier strv_free(l);
739d81ddd005fae2bb82edce5b8a6173c7c48b34Zbigniew Jędrzejewski-Szmek }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
edbced8a151c1b7ded685e2ec644950d2adec5f5Harald Hoyer
edbced8a151c1b7ded685e2ec644950d2adec5f5Harald Hoyer return 0;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier}
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic int show_status(DBusConnection *bus, char **args, unsigned n) {
739d81ddd005fae2bb82edce5b8a6173c7c48b34Zbigniew Jędrzejewski-Szmek _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier const char *interface = "";
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier int r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier DBusMessageIter iter, sub, sub2, sub3;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier StatusInfo info;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert(args);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = bus_method_call_with_reply(
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier bus,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "org.freedesktop.locale1",
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "/org/freedesktop/locale1",
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "org.freedesktop.DBus.Properties",
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "GetAll",
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier &reply,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier NULL,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier DBUS_TYPE_STRING, &interface,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier DBUS_TYPE_INVALID);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!dbus_message_iter_init(reply, &iter) ||
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("Failed to parse reply.");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return -EIO;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier zero(info);
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin dbus_message_iter_recurse(&iter, &sub);
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin const char *name;
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_DICT_ENTRY) {
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin log_error("Failed to parse reply.");
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin return -EIO;
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin }
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin dbus_message_iter_recurse(&sub, &sub2);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &name, true) < 0) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("Failed to parse reply.");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return -EIO;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (dbus_message_iter_get_arg_type(&sub2) != DBUS_TYPE_VARIANT) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("Failed to parse reply.");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return -EIO;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier dbus_message_iter_recurse(&sub2, &sub3);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = status_property(name, &sub3, &info);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("Failed to parse reply.");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier dbus_message_iter_next(&sub);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier print_status_info(&info);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier strv_free(info.locale);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return 0;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier}
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic int set_locale(DBusConnection *bus, char **args, unsigned n) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier dbus_bool_t interactive = true;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier DBusError error;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier DBusMessageIter iter;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier int r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert(bus);
bf3a947cb44f31359bba313e0252cbcc0dc95b03Evgeny Vereshchagin assert(args);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier dbus_error_init(&error);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier polkit_agent_open_if_enabled();
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier m = dbus_message_new_method_call(
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "org.freedesktop.locale1",
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "/org/freedesktop/locale1",
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "org.freedesktop.locale1",
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "SetLocale");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!m)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return log_oom();
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier dbus_message_iter_init_append(m, &iter);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = bus_append_strv_iter(&iter, args + 1);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return log_oom();
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &interactive))
4be4833ece2856e0cacc09f8f8b2c02b320751faMartin Pitt return log_oom();
7d023341c765c205068e33d23d63a4000ec211dfMartin Pitt
7d023341c765c205068e33d23d63a4000ec211dfMartin Pitt reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!reply) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("Failed to issue method call: %s", bus_error_message(&error));
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = -EIO;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier goto finish;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = 0;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
cffae62bcb6912fbaf1b7b282d9d170c9d308897Martin Pittfinish:
99877b7e3782a51b31bf191825f0335500f52fe5Harald Hoyer dbus_error_free(&error);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier}
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pittstatic int list_locales(DBusConnection *bus, char **args, unsigned n) {
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt /* Stolen from glibc... */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier struct locarhead {
e63b61be5350dbe92ea12e1eeb96dde251ed9292Evgeny Vereshchagin uint32_t magic;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Serial number. */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier uint32_t serial;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Name hash table. */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier uint32_t namehash_offset;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier uint32_t namehash_used;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier uint32_t namehash_size;
0fe15dc8ddddeb39a5cad1f4f4afa25fa074a5d1Evgeny Vereshchagin /* String table. */
0fe15dc8ddddeb39a5cad1f4f4afa25fa074a5d1Evgeny Vereshchagin uint32_t string_offset;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier uint32_t string_used;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier uint32_t string_size;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Table with locale records. */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier uint32_t locrectab_offset;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier uint32_t locrectab_used;
0fe15dc8ddddeb39a5cad1f4f4afa25fa074a5d1Evgeny Vereshchagin uint32_t locrectab_size;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* MD5 sum hash table. */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier uint32_t sumhash_offset;
417491f122b346a31cf8dc406c4f9195a5900cecEvgeny Vereshchagin uint32_t sumhash_used;
417491f122b346a31cf8dc406c4f9195a5900cecEvgeny Vereshchagin uint32_t sumhash_size;
417491f122b346a31cf8dc406c4f9195a5900cecEvgeny Vereshchagin };
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier struct namehashent {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Hash value of the name. */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier uint32_t hashval;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Offset of the name in the string table. */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier uint32_t name_offset;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Offset of the locale record. */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier uint32_t locrec_offset;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier };
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier const struct locarhead *h;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier const struct namehashent *e;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier const void *p = MAP_FAILED;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier _cleanup_close_ int fd = -1;
25b47f96d9601ff566257b2a31bfb5f4bd25d661Marko Myllynen _cleanup_strv_free_ char **l = NULL;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier char **j;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier Set *locales;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier size_t sz = 0;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier struct stat st;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier unsigned i;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier int r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier locales = set_new(string_hash_func, string_compare_func);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!locales)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return log_oom();
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier fd = open("/usr/lib/locale/locale-archive", O_RDONLY|O_NOCTTY|O_CLOEXEC);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (fd < 0) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("Failed to open locale archive: %m");
53d90f9582f96208b3674da823ad1a3d2c3b1aa4Martin Pitt r = -errno;
5c404f1ab8e96efedb983806443ca982a1b2a372Evgeny Vereshchagin goto finish;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (fstat(fd, &st) < 0) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("fstat() failed: %m");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = -errno;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier goto finish;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!S_ISREG(st.st_mode)) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("Archive file is not regular");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = -EBADMSG;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier goto finish;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (st.st_size < (off_t) sizeof(struct locarhead)) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("Archive has invalid size");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = -EBADMSG;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer goto finish;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier p = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (p == MAP_FAILED) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_error("Failed to map archive: %m");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = -errno;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer h = (const struct locarhead *) p;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (h->magic != 0xde020109 ||
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer h->namehash_offset + h->namehash_size > st.st_size ||
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer h->string_offset + h->string_size > st.st_size ||
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer h->locrectab_offset + h->locrectab_size > st.st_size ||
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer h->sumhash_offset + h->sumhash_size > st.st_size) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Invalid archive file.");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = -EBADMSG;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer e = (const struct namehashent*) ((const uint8_t*) p + h->namehash_offset);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer for (i = 0; i < h->namehash_size; i++) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer char *z;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (e[i].locrec_offset == 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer continue;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer z = strdup((char*) p + e[i].name_offset);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!z) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = log_oom();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = set_put(locales, z);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer free(z);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Failed to add locale: %s", strerror(-r));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer l = set_get_strv(locales);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!l) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = log_oom();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer set_free(locales);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer locales = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer strv_sort(l);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier pager_open_if_enabled();
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier STRV_FOREACH(j, l)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier puts(*j);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerfinish:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (p != MAP_FAILED)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer munmap((void*) p, sz);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer set_free_free(locales);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int set_vconsole_keymap(DBusConnection *bus, char **args, unsigned n) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer dbus_bool_t interactive = true, b;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *map, *toggle_map;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(bus);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(args);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (n > 3) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Too many arguments.");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return -EINVAL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer polkit_agent_open_if_enabled();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer map = args[1];
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer toggle_map = n > 2 ? args[2] : "";
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer b = arg_convert;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return bus_method_call_with_reply(
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer bus,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "org.freedesktop.locale1",
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "/org/freedesktop/locale1",
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "org.freedesktop.locale1",
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "SetVConsoleKeyboard",
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer &reply,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer NULL,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DBUS_TYPE_STRING, &map,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DBUS_TYPE_STRING, &toggle_map,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DBUS_TYPE_BOOLEAN, &b,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DBUS_TYPE_BOOLEAN, &interactive,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DBUS_TYPE_INVALID);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic Set *keymaps = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int nftw_cb(
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *fpath,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const struct stat *sb,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int tflag,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer struct FTW *ftwbuf) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer char *p, *e;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (tflag != FTW_F)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!endswith(fpath, ".map") &&
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer !endswith(fpath, ".map.gz"))
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer p = strdup(path_get_file_name(fpath));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!p)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return log_oom();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer e = endswith(p, ".map");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (e)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer *e = 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer e = endswith(p, ".map.gz");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (e)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer *e = 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = set_put(keymaps, p);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r == -EEXIST)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer free(p);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer else if (r < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Can't add keymap: %s", strerror(-r));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer free(p);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int list_vconsole_keymaps(DBusConnection *bus, char **args, unsigned n) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer char _cleanup_strv_free_ **l = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer char **i;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer keymaps = set_new(string_hash_func, string_compare_func);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!keymaps)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return log_oom();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer nftw("/usr/share/kbd/keymaps/", nftw_cb, 20, FTW_MOUNT|FTW_PHYS);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer nftw("/usr/lib/kbd/keymaps/", nftw_cb, 20, FTW_MOUNT|FTW_PHYS);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer nftw("/lib/kbd/keymaps/", nftw_cb, 20, FTW_MOUNT|FTW_PHYS);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer l = set_get_strv(keymaps);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!l) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer set_free_free(keymaps);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return log_oom();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer set_free(keymaps);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (strv_isempty(l)) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Couldn't find any console keymaps.");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return -ENOENT;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer strv_sort(l);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer pager_open_if_enabled();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer STRV_FOREACH(i, l)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer puts(*i);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int set_x11_keymap(DBusConnection *bus, char **args, unsigned n) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer dbus_bool_t interactive = true, b;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *layout, *model, *variant, *options;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(bus);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(args);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (n > 5) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Too many arguments.");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return -EINVAL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer polkit_agent_open_if_enabled();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer layout = args[1];
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer model = n > 2 ? args[2] : "";
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer variant = n > 3 ? args[3] : "";
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer options = n > 4 ? args[4] : "";
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer b = arg_convert;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return bus_method_call_with_reply(
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer bus,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "org.freedesktop.locale1",
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "/org/freedesktop/locale1",
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "org.freedesktop.locale1",
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "SetX11Keyboard",
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer &reply,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer NULL,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DBUS_TYPE_STRING, &layout,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DBUS_TYPE_STRING, &model,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DBUS_TYPE_STRING, &variant,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DBUS_TYPE_STRING, &options,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DBUS_TYPE_BOOLEAN, &b,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DBUS_TYPE_BOOLEAN, &interactive,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DBUS_TYPE_INVALID);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int help(void) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer printf("%s [OPTIONS...] COMMAND ...\n\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "Query or change system time and date settings.\n\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer " -h --help Show this help\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer " --version Show package version\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer " --no-convert Don't convert keyboard mappings\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer " --no-pager Do not pipe output into a pager\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer " --no-ask-password Do not prompt for password\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer " -H --host=[USER@]HOST Operate on remote host\n\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "Commands:\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer " status Show current locale settings\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer " set-locale LOCALE... Set system locale\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer " list-locales Show known locales\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer " set-keymap MAP [MAP] Set virtual console keyboard mapping\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer " list-keymaps Show known virtual console keyboard mappings\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer " set-x11-keymap LAYOUT [MODEL] [VARIANT] [OPTIONS]\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer " Set X11 keyboard mapping\n",
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer program_invocation_short_name);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int parse_argv(int argc, char *argv[]) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer enum {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_VERSION = 0x100,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_NO_PAGER,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_NO_CONVERT,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_NO_ASK_PASSWORD
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer };
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer static const struct option options[] = {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "help", no_argument, NULL, 'h' },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "version", no_argument, NULL, ARG_VERSION },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "no-pager", no_argument, NULL, ARG_NO_PAGER },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "host", required_argument, NULL, 'H' },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "privileged", no_argument, NULL, 'P' },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "no-convert", no_argument, NULL, ARG_NO_CONVERT },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { NULL, 0, NULL, 0 }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer };
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int c;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(argc >= 0);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(argv);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer while ((c = getopt_long(argc, argv, "has:H:P", options, NULL)) >= 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer switch (c) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case 'h':
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer help();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case ARG_VERSION:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer puts(PACKAGE_STRING);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer puts(DISTRIBUTION);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer puts(SYSTEMD_FEATURES);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case 'P':
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_transport = TRANSPORT_POLKIT;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case 'H':
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_transport = TRANSPORT_SSH;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_host = optarg;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case ARG_NO_CONVERT:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_convert = false;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case ARG_NO_PAGER:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_no_pager = true;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case '?':
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return -EINVAL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer default:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Unknown option code %c", c);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return -EINVAL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 1;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int localectl_main(DBusConnection *bus, int argc, char *argv[], DBusError *error) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer static const struct {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char* verb;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const enum {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer MORE,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer LESS,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer EQUAL
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer } argc_cmp;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const int argc;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int (* const dispatch)(DBusConnection *bus, char **args, unsigned n);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer } verbs[] = {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "status", LESS, 1, show_status },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "set-locale", MORE, 2, set_locale },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "list-locales", EQUAL, 1, list_locales },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "set-keymap", MORE, 2, set_vconsole_keymap },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "list-keymaps", EQUAL, 1, list_vconsole_keymaps },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "set-x11-keymap", MORE, 2, set_x11_keymap },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer };
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int left;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer unsigned i;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(argc >= 0);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(argv);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(error);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer left = argc - optind;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (left <= 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Special rule: no arguments means "status" */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer i = 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer else {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (streq(argv[optind], "help")) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer help();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer for (i = 0; i < ELEMENTSOF(verbs); i++)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (streq(argv[optind], verbs[i].verb))
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (i >= ELEMENTSOF(verbs)) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Unknown operation %s", argv[optind]);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return -EINVAL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer switch (verbs[i].argc_cmp) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case EQUAL:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (left != verbs[i].argc) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Invalid number of arguments.");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return -EINVAL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case MORE:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (left < verbs[i].argc) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Too few arguments.");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return -EINVAL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case LESS:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (left > verbs[i].argc) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Too many arguments.");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return -EINVAL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer default:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert_not_reached("Unknown comparison operator.");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!bus) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Failed to get D-Bus connection: %s", error->message);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return -EIO;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return verbs[i].dispatch(bus, argv + optind, left);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerint main(int argc, char *argv[]) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int r, retval = EXIT_FAILURE;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DBusConnection *bus = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DBusError error;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer dbus_error_init(&error);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer setlocale(LC_ALL, "");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_parse_environment();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_open();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = parse_argv(argc, argv);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer else if (r == 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer retval = EXIT_SUCCESS;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (arg_transport == TRANSPORT_NORMAL)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer else if (arg_transport == TRANSPORT_POLKIT)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer bus_connect_system_polkit(&bus, &error);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer else if (arg_transport == TRANSPORT_SSH)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer bus_connect_system_ssh(NULL, arg_host, &bus, &error);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer else
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert_not_reached("Uh, invalid transport...");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = localectl_main(bus, argc, argv, &error);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer retval = r < 0 ? EXIT_FAILURE : r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerfinish:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (bus) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer dbus_connection_flush(bus);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer dbus_connection_close(bus);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer dbus_connection_unref(bus);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer dbus_error_free(&error);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer dbus_shutdown();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer pager_close();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return retval;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer