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/>.
20 #if defined(__GLIBC__)
21 # include <bits/local_lim.h>
22 #endif // defined(__GLIBC__)
27 #include <sys/utsname.h>
30 //#include "fd-util.h"
32 #include "hostname-util.h"
34 #include "string-util.h"
36 #if 0 /// UNNEEDED by elogind
37 bool hostname_is_set(void) {
40 assert_se(uname(&u) >= 0);
42 if (isempty(u.nodename))
45 /* This is the built-in kernel default host name */
46 if (streq(u.nodename, "(none)"))
52 char* gethostname_malloc(void) {
55 assert_se(uname(&u) >= 0);
57 if (isempty(u.nodename) || streq(u.nodename, "(none)"))
58 return strdup(u.sysname);
60 return strdup(u.nodename);
64 static bool hostname_valid_char(char c) {
66 (c >= 'a' && c <= 'z') ||
67 (c >= 'A' && c <= 'Z') ||
68 (c >= '0' && c <= '9') ||
75 * Check if s looks like a valid host name or FQDN. This does not do
76 * full DNS validation, but only checks if the name is composed of
77 * allowed characters and the length is not above the maximum allowed
78 * by Linux (c.f. dns_name_is_valid()). Trailing dot is allowed if
79 * allow_trailing_dot is true and at least two components are present
80 * in the name. Note that due to the restricted charset and length
81 * this call is substantially more conservative than
82 * dns_name_is_valid().
84 bool hostname_is_valid(const char *s, bool allow_trailing_dot) {
92 /* Doesn't accept empty hostnames, hostnames with
93 * leading dots, and hostnames with multiple dots in a
94 * sequence. Also ensures that the length stays below
97 for (p = s, dot = true; *p; p++) {
105 if (!hostname_valid_char(*p))
112 if (dot && (n_dots < 2 || !allow_trailing_dot))
115 if (p-s > HOST_NAME_MAX) /* Note that HOST_NAME_MAX is 64 on
116 * Linux, but DNS allows domain names
117 * up to 255 characters */
123 #if 0 /// UNNEEDED by elogind
124 char* hostname_cleanup(char *s) {
130 for (p = s, d = s, dot = true; *p; p++) {
137 } else if (hostname_valid_char(*p)) {
149 strshorten(s, HOST_NAME_MAX);
155 bool is_localhost(const char *hostname) {
158 /* This tries to identify local host and domain names
159 * described in RFC6761 plus the redhatism of .localdomain */
161 return strcaseeq(hostname, "localhost") ||
162 strcaseeq(hostname, "localhost.") ||
163 strcaseeq(hostname, "localdomain.") ||
164 strcaseeq(hostname, "localdomain") ||
165 endswith_no_case(hostname, ".localhost") ||
166 endswith_no_case(hostname, ".localhost.") ||
167 endswith_no_case(hostname, ".localdomain") ||
168 endswith_no_case(hostname, ".localdomain.");
171 #if 0 /// UNNEEDED by elogind
172 bool is_gateway_hostname(const char *hostname) {
175 /* This tries to identify the valid syntaxes for the our
176 * synthetic "gateway" host. */
179 strcaseeq(hostname, "gateway") ||
180 strcaseeq(hostname, "gateway.");
183 int sethostname_idempotent(const char *s) {
184 char buf[HOST_NAME_MAX + 1] = {};
188 if (gethostname(buf, sizeof(buf)) < 0)
194 if (sethostname(s, strlen(s)) < 0)
200 int read_hostname_config(const char *path, char **hostname) {
201 _cleanup_fclose_ FILE *f = NULL;
208 f = fopen(path, "re");
212 /* may have comments, ignore them */
213 FOREACH_LINE(l, f, return -errno) {
215 if (l[0] != '\0' && l[0] != '#') {
216 /* found line with value */
217 name = hostname_cleanup(l);
226 /* no non-empty line found */