1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2015 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <sys/utsname.h>
26 #include "hostname-util.h"
28 /// UNNEEDED by elogind
30 bool hostname_is_set(void) {
33 assert_se(uname(&u) >= 0);
35 if (isempty(u.nodename))
38 /* This is the built-in kernel default host name */
39 if (streq(u.nodename, "(none)"))
45 char* gethostname_malloc(void) {
48 assert_se(uname(&u) >= 0);
50 if (isempty(u.nodename) || streq(u.nodename, "(none)"))
51 return strdup(u.sysname);
53 return strdup(u.nodename);
57 static bool hostname_valid_char(char c) {
59 (c >= 'a' && c <= 'z') ||
60 (c >= 'A' && c <= 'Z') ||
61 (c >= '0' && c <= '9') ||
67 bool hostname_is_valid(const char *s) {
74 /* Doesn't accept empty hostnames, hostnames with trailing or
75 * leading dots, and hostnames with multiple dots in a
76 * sequence. Also ensures that the length stays below
79 for (p = s, dot = true; *p; p++) {
86 if (!hostname_valid_char(*p))
96 if (p-s > HOST_NAME_MAX)
102 char* hostname_cleanup(char *s, bool lowercase) {
108 for (p = s, d = s, dot = true; *p; p++) {
115 } else if (hostname_valid_char(*p)) {
116 *(d++) = lowercase ? tolower(*p) : *p;
127 strshorten(s, HOST_NAME_MAX);
132 bool is_localhost(const char *hostname) {
135 /* This tries to identify local host and domain names
136 * described in RFC6761 plus the redhatism of .localdomain */
138 return streq(hostname, "localhost") ||
139 streq(hostname, "localhost.") ||
140 streq(hostname, "localdomain.") ||
141 streq(hostname, "localdomain") ||
142 endswith(hostname, ".localhost") ||
143 endswith(hostname, ".localhost.") ||
144 endswith(hostname, ".localdomain") ||
145 endswith(hostname, ".localdomain.");
148 /// UNNEEDED by elogind
150 int sethostname_idempotent(const char *s) {
151 char buf[HOST_NAME_MAX + 1] = {};
155 if (gethostname(buf, sizeof(buf)) < 0)
161 if (sethostname(s, strlen(s)) < 0)
167 int read_hostname_config(const char *path, char **hostname) {
168 _cleanup_fclose_ FILE *f = NULL;
175 f = fopen(path, "re");
179 /* may have comments, ignore them */
180 FOREACH_LINE(l, f, return -errno) {
182 if (l[0] != '\0' && l[0] != '#') {
183 /* found line with value */
184 name = hostname_cleanup(l, false);
193 /* no non-empty line found */