2 This file is part of systemd.
4 Copyright 2015 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 #include <sys/utsname.h>
27 //#include "fd-util.h"
29 #include "hostname-util.h"
31 #include "string-util.h"
33 #if 0 /// UNNEEDED by elogind
34 bool hostname_is_set(void) {
37 assert_se(uname(&u) >= 0);
39 if (isempty(u.nodename))
42 /* This is the built-in kernel default host name */
43 if (streq(u.nodename, "(none)"))
50 char* gethostname_malloc(void) {
53 /* This call tries to return something useful, either the actual hostname
54 * or it makes something up. The only reason it might fail is OOM.
55 * It might even return "localhost" if that's set. */
57 assert_se(uname(&u) >= 0);
59 if (isempty(u.nodename) || streq(u.nodename, "(none)"))
60 #if 0 /// elogind has no hostnamed and such nonsense
61 return strdup(FALLBACK_HOSTNAME);
63 return strdup("localhost");
66 return strdup(u.nodename);
69 #if 0 /// UNNEEDED by elogind
70 int gethostname_strict(char **ret) {
74 /* This call will rather fail than make up a name. It will not return "localhost" either. */
76 assert_se(uname(&u) >= 0);
78 if (isempty(u.nodename))
81 if (streq(u.nodename, "(none)"))
84 if (is_localhost(u.nodename))
87 k = strdup(u.nodename);
96 static bool hostname_valid_char(char c) {
98 (c >= 'a' && c <= 'z') ||
99 (c >= 'A' && c <= 'Z') ||
100 (c >= '0' && c <= '9') ||
107 * Check if s looks like a valid host name or FQDN. This does not do
108 * full DNS validation, but only checks if the name is composed of
109 * allowed characters and the length is not above the maximum allowed
110 * by Linux (c.f. dns_name_is_valid()). Trailing dot is allowed if
111 * allow_trailing_dot is true and at least two components are present
112 * in the name. Note that due to the restricted charset and length
113 * this call is substantially more conservative than
114 * dns_name_is_valid().
116 bool hostname_is_valid(const char *s, bool allow_trailing_dot) {
124 /* Doesn't accept empty hostnames, hostnames with
125 * leading dots, and hostnames with multiple dots in a
126 * sequence. Also ensures that the length stays below
129 for (p = s, dot = true; *p; p++) {
137 if (!hostname_valid_char(*p))
144 if (dot && (n_dots < 2 || !allow_trailing_dot))
147 if (p-s > HOST_NAME_MAX) /* Note that HOST_NAME_MAX is 64 on
148 * Linux, but DNS allows domain names
149 * up to 255 characters */
155 #if 0 /// UNNEEDED by elogind
156 char* hostname_cleanup(char *s) {
162 strshorten(s, HOST_NAME_MAX);
164 for (p = s, d = s, dot = true; *p; p++) {
171 } else if (hostname_valid_char(*p)) {
186 bool is_localhost(const char *hostname) {
189 /* This tries to identify local host and domain names
190 * described in RFC6761 plus the redhatism of localdomain */
192 return strcaseeq(hostname, "localhost") ||
193 strcaseeq(hostname, "localhost.") ||
194 strcaseeq(hostname, "localhost.localdomain") ||
195 strcaseeq(hostname, "localhost.localdomain.") ||
196 endswith_no_case(hostname, ".localhost") ||
197 endswith_no_case(hostname, ".localhost.") ||
198 endswith_no_case(hostname, ".localhost.localdomain") ||
199 endswith_no_case(hostname, ".localhost.localdomain.");
202 #if 0 /// UNNEEDED by elogind
203 bool is_gateway_hostname(const char *hostname) {
206 /* This tries to identify the valid syntaxes for the our
207 * synthetic "gateway" host. */
210 strcaseeq(hostname, "gateway") ||
211 strcaseeq(hostname, "gateway.");
214 int sethostname_idempotent(const char *s) {
215 char buf[HOST_NAME_MAX + 1] = {};
219 if (gethostname(buf, sizeof(buf)) < 0)
225 if (sethostname(s, strlen(s)) < 0)
231 int read_hostname_config(const char *path, char **hostname) {
232 _cleanup_fclose_ FILE *f = NULL;
239 f = fopen(path, "re");
243 /* may have comments, ignore them */
244 FOREACH_LINE(l, f, return -errno) {
246 if (l[0] != '\0' && l[0] != '#') {
247 /* found line with value */
248 name = hostname_cleanup(l);
257 /* no non-empty line found */