hostnamed.c revision f401e48c2db22ff9d1a05885b5599bebf19c2707
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering This file is part of systemd.
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering Copyright 2011 Lennart 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 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 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 DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \
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 Poetteringstatic void free_data(void) {
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering for (p = 0; p < _PROP_MAX; p++) {
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poetteringstatic int read_data(void) {
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering data[PROP_HOSTNAME] = gethostname_malloc();
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering r = read_one_line_file("/etc/hostname", &data[PROP_STATIC_HOSTNAME]);
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering if (r < 0 && r != -ENOENT)
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering r = parse_env_file("/etc/machine-info", NEWLINE,
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering "PRETTY_HOSTNAME", &data[PROP_PRETTY_HOSTNAME],
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering if (r < 0 && r != -ENOENT)
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poetteringstatic bool check_nss(void) {
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering if ((dl = dlopen("libnss_myhostname.so.2", RTLD_LAZY))) {
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poetteringstatic const char* fallback_icon_name(void) {
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering#if defined(__i386__) || defined(__x86_64__)
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering return "computer-vm";
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering#if defined(__i386__) || defined(__x86_64__)
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering r = read_one_line_file("/sys/class/dmi/id/chassis_type", &type);
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 See the SMBIOS Specification 2.7.1 section 7.4.1 for
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering details about the values listed here:
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.7.1.pdf
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering return "computer-desktop";
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering return "computer-laptop";
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering return "computer-server";
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poetteringstatic int write_data_static_hostname(void) {
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering if (isempty(data[PROP_STATIC_HOSTNAME])) {
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering return write_one_line_file_atomic("/etc/hostname", data[PROP_STATIC_HOSTNAME]);
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poetteringstatic int write_data_other(void) {
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering static const char * const name[_PROP_MAX] = {
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering [PROP_PRETTY_HOSTNAME] = "PRETTY_HOSTNAME",
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering r = load_env_file("/etc/machine-info", &l);
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering if (r < 0 && r != -ENOENT)
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering if (asprintf(&t, "%s=%s", name[p], strempty(data[p])) < 0) {
85210bffd8363e491b4c31f2d09404f9869ad0c7Lennart Poettering r = write_env_file("/etc/machine-info", l);
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poetteringstatic int bus_hostname_append_icon_name(DBusMessageIter *i, const char *property, void *userdata) {
91a031725396faebf51ea7b5475532453b8d6df3Lennart Poettering return bus_property_append_string(i, property, (void*) name);
void *userdata) {
{ "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]},
const char *name;
if (!dbus_message_get_args(
&error,
r = verify_polkit(connection, message, "org.freedesktop.hostname1.set-hostname", interactive, &error);
goto oom;
r = write_data_hostname();
"/org/freedesktop/hostname1",
"org.freedesktop.hostname1",
if (!changed)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetStaticHostname")) {
const char *name;
if (!dbus_message_get_args(
&error,
r = verify_polkit(connection, message, "org.freedesktop.hostname1.set-static-hostname", interactive, &error);
goto oom;
r = write_data_static_hostname();
"/org/freedesktop/hostname1",
"org.freedesktop.hostname1",
if (!changed)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetPrettyHostname") ||
const char *name;
if (!dbus_message_get_args(
&error,
k = streq(dbus_message_get_member(message), "SetPrettyHostname") ? PROP_PRETTY_HOSTNAME : PROP_ICON_NAME;
"org.freedesktop.hostname1.set-static-hostname" :
goto oom;
data[k] = h;
r = write_data_other();
log_info("Changed %s to '%s'", k == PROP_PRETTY_HOSTNAME ? "pretty host name" : "icon name", strempty(data[k]));
"/org/freedesktop/hostname1",
"org.freedesktop.hostname1",
if (!changed)
goto oom;
return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, properties);
goto oom;
goto oom;
if (changed) {
goto oom;
return DBUS_HANDLER_RESULT_HANDLED;
oom:
if (reply)
if (changed)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
if (!bus) {
r = -ECONNREFUSED;
goto fail;
if (!dbus_connection_register_object_path(bus, "/org/freedesktop/hostname1", &hostname_vtable, NULL)) {
r = -ENOMEM;
goto fail;
if (dbus_bus_request_name(bus, "org.freedesktop.hostname1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error) < 0) {
r = -EEXIST;
goto fail;
if (_bus)
fail:
log_open();
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!");
r = read_data();
goto finish;
goto finish;
free_data();
if (bus) {