hostnamed.c revision f401e48c2db22ff9d1a05885b5599bebf19c2707
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering/***
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering This file is part of systemd.
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering Copyright 2011 Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering systemd is free software; you can redistribute it and/or modify it
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering under the terms of the GNU General Public License as published by
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering the Free Software Foundation; either version 2 of the License, or
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering (at your option) any later version.
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering systemd is distributed in the hope that it will be useful, but
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering General Public License for more details.
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering You should have received a copy of the GNU General Public License
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering***/
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering#include <dbus/dbus.h>
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering#include <errno.h>
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering#include <string.h>
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering#include <unistd.h>
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering#include <dlfcn.h>
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering#include "util.h"
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering#include "strv.h"
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering#include "dbus-common.h"
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering#include "polkit.h"
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering#define INTROSPECTION \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering "<node>\n" \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering " <interface name=\"org.freedesktop.hostname1\">\n" \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering " <property name=\"Hostname\" type=\"s\" access=\"read\"/>\n" \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering " <property name=\"StaticHostname\" type=\"s\" access=\"read\"/>\n" \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering " <property name=\"PrettyHostname\" type=\"s\" access=\"read\"/>\n" \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering " <property name=\"IconName\" type=\"s\" access=\"read\"/>\n" \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering " <method name=\"SetHostname\">\n" \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering " <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering " </method>\n" \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering " <method name=\"SetStaticHostname\">\n" \
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \
19125c205aa6084c225b5c11cc6dcbe18c6dbcc0Lennart Poettering " <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
19125c205aa6084c225b5c11cc6dcbe18c6dbcc0Lennart Poettering " </method>\n" \
95694951a0905dd748c6902268b15e3a56632da2Lennart Poettering " <method name=\"SetPrettyHostname\">\n" \
95694951a0905dd748c6902268b15e3a56632da2Lennart Poettering " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \
95694951a0905dd748c6902268b15e3a56632da2Lennart Poettering " <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering " </method>\n" \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering " <method name=\"SetIconName\">\n" \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering " <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering " </method>\n" \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering " </interface>\n" \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering BUS_PROPERTIES_INTERFACE \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering BUS_INTROSPECTABLE_INTERFACE \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering BUS_PEER_INTERFACE \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering "</node>\n"
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering#define INTERFACES_LIST \
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering BUS_GENERIC_INTERFACES_LIST \
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering "org.freedesktop.hostname1\0"
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poetteringenum {
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering PROP_HOSTNAME,
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering PROP_STATIC_HOSTNAME,
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering PROP_PRETTY_HOSTNAME,
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering PROP_ICON_NAME,
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering _PROP_MAX
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering};
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poetteringstatic char *data[_PROP_MAX] = {
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering NULL,
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering NULL,
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering NULL,
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering NULL
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering};
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poetteringstatic void free_data(void) {
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering int p;
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering for (p = 0; p < _PROP_MAX; p++) {
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering free(data[p]);
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering data[p] = NULL;
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering }
bb31a4ac1997c189a344caf554f34c6aabc71aa7Thomas Hindoe Paaboel Andersen}
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poetteringstatic int read_data(void) {
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering int r;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering free_data();
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering data[PROP_HOSTNAME] = gethostname_malloc();
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering if (!data[PROP_HOSTNAME])
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering return -ENOMEM;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering r = read_one_line_file("/etc/hostname", &data[PROP_STATIC_HOSTNAME]);
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering if (r < 0 && r != -ENOENT)
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering return r;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering r = parse_env_file("/etc/machine-info", NEWLINE,
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering "PRETTY_HOSTNAME", &data[PROP_PRETTY_HOSTNAME],
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering "ICON_NAME", &data[PROP_ICON_NAME],
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering NULL);
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering if (r < 0 && r != -ENOENT)
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering return r;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering return 0;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering}
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poetteringstatic bool check_nss(void) {
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering void *dl;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering if ((dl = dlopen("libnss_myhostname.so.2", RTLD_LAZY))) {
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering dlclose(dl);
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering return true;
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering }
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering return false;
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering}
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poetteringstatic const char* fallback_icon_name(void) {
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering#if defined(__i386__) || defined(__x86_64__)
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering int r;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering char *type;
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering unsigned t;
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering#endif
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering if (detect_virtualization(NULL) > 0)
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering return "computer-vm";
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering#if defined(__i386__) || defined(__x86_64__)
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering r = read_one_line_file("/sys/class/dmi/id/chassis_type", &type);
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering if (r < 0)
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering return NULL;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering r = safe_atou(type, &t);
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering free(type);
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering if (r < 0)
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering return NULL;
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering /* We only list the really obvious cases here. The DMI data is
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering unreliable enough, so let's not do any additional guesswork
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering on top of that.
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering See the SMBIOS Specification 2.7.1 section 7.4.1 for
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering details about the values listed here:
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.7.1.pdf
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering */
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering switch (t) {
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering case 0x3:
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering case 0x4:
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering case 0x6:
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering case 0x7:
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering return "computer-desktop";
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering case 0x9:
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering case 0xA:
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering case 0xE:
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering return "computer-laptop";
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering case 0x11:
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering case 0x1C:
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering return "computer-server";
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering }
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering#endif
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering return NULL;
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering}
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poetteringstatic int write_data_hostname(void) {
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering const char *hn;
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering if (isempty(data[PROP_HOSTNAME]))
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering hn = "localhost";
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering else
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering hn = data[PROP_HOSTNAME];
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering if (sethostname(hn, strlen(hn)) < 0)
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering return -errno;
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering return 0;
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering}
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poetteringstatic int write_data_static_hostname(void) {
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering if (isempty(data[PROP_STATIC_HOSTNAME])) {
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering if (unlink("/etc/hostname") < 0)
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering return errno == ENOENT ? 0 : -errno;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering return 0;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering }
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering return write_one_line_file_atomic("/etc/hostname", data[PROP_STATIC_HOSTNAME]);
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering}
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poetteringstatic int write_data_other(void) {
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering static const char * const name[_PROP_MAX] = {
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering [PROP_PRETTY_HOSTNAME] = "PRETTY_HOSTNAME",
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering [PROP_ICON_NAME] = "ICON_NAME"
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering };
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering char **l = NULL;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering int r, p;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering r = load_env_file("/etc/machine-info", &l);
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering if (r < 0 && r != -ENOENT)
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering return r;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering for (p = 2; p < _PROP_MAX; p++) {
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering char *t, **u;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering assert(name[p]);
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering if (isempty(data[p])) {
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering l = strv_env_unset(l, name[p]);
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering continue;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering }
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering if (asprintf(&t, "%s=%s", name[p], strempty(data[p])) < 0) {
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering strv_free(l);
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering return -ENOMEM;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering }
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering u = strv_env_set(l, t);
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering free(t);
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering strv_free(l);
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering if (!u)
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering return -ENOMEM;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering l = u;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering }
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering if (strv_isempty(l)) {
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering if (unlink("/etc/machine-info") < 0)
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering return errno == ENOENT ? 0 : -errno;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering return 0;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering }
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering r = write_env_file("/etc/machine-info", l);
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering strv_free(l);
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering return r;
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering}
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poetteringstatic int bus_hostname_append_icon_name(DBusMessageIter *i, const char *property, void *userdata) {
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering const char *name;
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering assert(i);
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering assert(property);
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering if (isempty(data[PROP_ICON_NAME]))
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering name = fallback_icon_name();
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering else
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering name = data[PROP_ICON_NAME];
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering return bus_property_append_string(i, property, (void*) name);
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering}
static DBusHandlerResult hostname_message_handler(
DBusConnection *connection,
DBusMessage *message,
void *userdata) {
const BusProperty properties[] = {
{ "org.freedesktop.hostname1", "Hostname", bus_property_append_string, "s", data[PROP_HOSTNAME]},
{ "org.freedesktop.hostname1", "StaticHostname", bus_property_append_string, "s", data[PROP_STATIC_HOSTNAME]},
{ "org.freedesktop.hostname1", "PrettyHostname", bus_property_append_string, "s", data[PROP_PRETTY_HOSTNAME]},
{ "org.freedesktop.hostname1", "IconName", bus_hostname_append_icon_name, "s", data[PROP_ICON_NAME]},
{ NULL, NULL, NULL, NULL, NULL }
};
DBusMessage *reply = NULL, *changed = NULL;
DBusError error;
int r;
assert(connection);
assert(message);
dbus_error_init(&error);
if (dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetHostname")) {
const char *name;
dbus_bool_t interactive;
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_BOOLEAN, &interactive,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
if (isempty(name))
name = data[PROP_STATIC_HOSTNAME];
if (isempty(name))
name = "localhost";
if (!hostname_is_valid(name))
return bus_send_error_reply(connection, message, NULL, -EINVAL);
if (!streq_ptr(name, data[PROP_HOSTNAME])) {
char *h;
r = verify_polkit(connection, message, "org.freedesktop.hostname1.set-hostname", interactive, &error);
if (r < 0)
return bus_send_error_reply(connection, message, &error, r);
h = strdup(name);
if (!h)
goto oom;
free(data[PROP_HOSTNAME]);
data[PROP_HOSTNAME] = h;
r = write_data_hostname();
if (r < 0) {
log_error("Failed to set host name: %s", strerror(-r));
return bus_send_error_reply(connection, message, NULL, r);
}
log_info("Changed host name to '%s'", strempty(data[PROP_HOSTNAME]));
changed = bus_properties_changed_new(
"/org/freedesktop/hostname1",
"org.freedesktop.hostname1",
"Hostname\0");
if (!changed)
goto oom;
}
} else if (dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetStaticHostname")) {
const char *name;
dbus_bool_t interactive;
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_BOOLEAN, &interactive,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
if (isempty(name))
name = NULL;
if (!streq_ptr(name, data[PROP_STATIC_HOSTNAME])) {
r = verify_polkit(connection, message, "org.freedesktop.hostname1.set-static-hostname", interactive, &error);
if (r < 0)
return bus_send_error_reply(connection, message, &error, r);
if (isempty(name)) {
free(data[PROP_STATIC_HOSTNAME]);
data[PROP_STATIC_HOSTNAME] = NULL;
} else {
char *h;
if (!hostname_is_valid(name))
return bus_send_error_reply(connection, message, NULL, -EINVAL);
h = strdup(name);
if (!h)
goto oom;
free(data[PROP_STATIC_HOSTNAME]);
data[PROP_STATIC_HOSTNAME] = h;
}
r = write_data_static_hostname();
if (r < 0) {
log_error("Failed to write static host name: %s", strerror(-r));
return bus_send_error_reply(connection, message, NULL, r);
}
log_info("Changed static host name to '%s'", strempty(data[PROP_HOSTNAME]));
changed = bus_properties_changed_new(
"/org/freedesktop/hostname1",
"org.freedesktop.hostname1",
"StaticHostname\0");
if (!changed)
goto oom;
}
} else if (dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetPrettyHostname") ||
dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetIconName")) {
const char *name;
dbus_bool_t interactive;
int k;
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_BOOLEAN, &interactive,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
if (isempty(name))
name = NULL;
k = streq(dbus_message_get_member(message), "SetPrettyHostname") ? PROP_PRETTY_HOSTNAME : PROP_ICON_NAME;
if (!streq_ptr(name, data[k])) {
/* Since the pretty hostname should always be
* changed at the same time as the static one,
* use the same policy action for both... */
r = verify_polkit(connection, message, k == PROP_PRETTY_HOSTNAME ?
"org.freedesktop.hostname1.set-static-hostname" :
"org.freedesktop.hostname1.set-machine-info", interactive, &error);
if (r < 0)
return bus_send_error_reply(connection, message, &error, r);
if (isempty(name)) {
free(data[k]);
data[k] = NULL;
} else {
char *h;
h = strdup(name);
if (!h)
goto oom;
free(data[k]);
data[k] = h;
}
r = write_data_other();
if (r < 0) {
log_error("Failed to write machine info: %s", strerror(-r));
return bus_send_error_reply(connection, message, NULL, r);
}
log_info("Changed %s to '%s'", k == PROP_PRETTY_HOSTNAME ? "pretty host name" : "icon name", strempty(data[k]));
changed = bus_properties_changed_new(
"/org/freedesktop/hostname1",
"org.freedesktop.hostname1",
k == PROP_PRETTY_HOSTNAME ? "PrettyHostname\0" : "IconName\0");
if (!changed)
goto oom;
}
} else
return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, properties);
if (!(reply = dbus_message_new_method_return(message)))
goto oom;
if (!dbus_connection_send(connection, reply, NULL))
goto oom;
dbus_message_unref(reply);
reply = NULL;
if (changed) {
if (!dbus_connection_send(connection, changed, NULL))
goto oom;
dbus_message_unref(changed);
}
return DBUS_HANDLER_RESULT_HANDLED;
oom:
if (reply)
dbus_message_unref(reply);
if (changed)
dbus_message_unref(changed);
dbus_error_free(&error);
return DBUS_HANDLER_RESULT_NEED_MEMORY;
}
static int connect_bus(DBusConnection **_bus) {
static const DBusObjectPathVTable hostname_vtable = {
.message_function = hostname_message_handler
};
DBusError error;
DBusConnection *bus = NULL;
int r;
assert(_bus);
dbus_error_init(&error);
bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
if (!bus) {
log_error("Failed to get system D-Bus connection: %s", error.message);
r = -ECONNREFUSED;
goto fail;
}
if (!dbus_connection_register_object_path(bus, "/org/freedesktop/hostname1", &hostname_vtable, NULL)) {
log_error("Not enough memory");
r = -ENOMEM;
goto fail;
}
if (dbus_bus_request_name(bus, "org.freedesktop.hostname1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error) < 0) {
log_error("Failed to register name on bus: %s", error.message);
r = -EEXIST;
goto fail;
}
if (_bus)
*_bus = bus;
return 0;
fail:
dbus_connection_close(bus);
dbus_connection_unref(bus);
dbus_error_free(&error);
return r;
}
int main(int argc, char *argv[]) {
int r;
DBusConnection *bus = NULL;
log_set_target(LOG_TARGET_AUTO);
log_parse_environment();
log_open();
if (argc != 1) {
log_error("This program takes no arguments.");
r = -EINVAL;
goto finish;
}
if (!check_nss())
log_warning("Warning: nss-myhostname is not installed. Changing the local hostname might make it unresolveable. Please install nss-myhostname!");
umask(0022);
r = read_data();
if (r < 0) {
log_error("Failed to read hostname data: %s", strerror(-r));
goto finish;
}
r = connect_bus(&bus);
if (r < 0)
goto finish;
while (dbus_connection_read_write_dispatch(bus, -1))
;
r = 0;
finish:
free_data();
if (bus) {
dbus_connection_flush(bus);
dbus_connection_close(bus);
dbus_connection_unref(bus);
}
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}