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/>.
23 #include <sys/utsname.h>
25 //#include "fd-util.h"
27 #include "hostname-util.h"
28 #include "string-util.h"
31 #if 0 /// UNNEEDED by elogind
32 bool hostname_is_set(void) {
35 assert_se(uname(&u) >= 0);
37 if (isempty(u.nodename))
40 /* This is the built-in kernel default host name */
41 if (streq(u.nodename, "(none)"))
47 char* gethostname_malloc(void) {
50 assert_se(uname(&u) >= 0);
52 if (isempty(u.nodename) || streq(u.nodename, "(none)"))
53 return strdup(u.sysname);
55 return strdup(u.nodename);
59 static bool hostname_valid_char(char c) {
61 (c >= 'a' && c <= 'z') ||
62 (c >= 'A' && c <= 'Z') ||
63 (c >= '0' && c <= '9') ||
70 * Check if s looks like a valid host name or FQDN. This does not do
71 * full DNS validation, but only checks if the name is composed of
72 * allowed characters and the length is not above the maximum allowed
73 * by Linux (c.f. dns_name_is_valid()). Trailing dot is allowed if
74 * allow_trailing_dot is true and at least two components are present
75 * in the name. Note that due to the restricted charset and length
76 * this call is substantially more conservative than
77 * dns_name_is_valid().
79 bool hostname_is_valid(const char *s, bool allow_trailing_dot) {
87 /* Doesn't accept empty hostnames, hostnames with
88 * leading dots, and hostnames with multiple dots in a
89 * sequence. Also ensures that the length stays below
92 for (p = s, dot = true; *p; p++) {
100 if (!hostname_valid_char(*p))
107 if (dot && (n_dots < 2 || !allow_trailing_dot))
110 if (p-s > HOST_NAME_MAX) /* Note that HOST_NAME_MAX is 64 on
111 * Linux, but DNS allows domain names
112 * up to 255 characters */
118 #if 0 /// UNNEEDED by elogind
119 char* hostname_cleanup(char *s) {
125 for (p = s, d = s, dot = true; *p; p++) {
132 } else if (hostname_valid_char(*p)) {
144 strshorten(s, HOST_NAME_MAX);
150 bool is_localhost(const char *hostname) {
153 /* This tries to identify local host and domain names
154 * described in RFC6761 plus the redhatism of .localdomain */
156 return strcaseeq(hostname, "localhost") ||
157 strcaseeq(hostname, "localhost.") ||
158 strcaseeq(hostname, "localdomain.") ||
159 strcaseeq(hostname, "localdomain") ||
160 endswith_no_case(hostname, ".localhost") ||
161 endswith_no_case(hostname, ".localhost.") ||
162 endswith_no_case(hostname, ".localdomain") ||
163 endswith_no_case(hostname, ".localdomain.");
166 #if 0 /// UNNEEDED by elogind
167 bool is_gateway_hostname(const char *hostname) {
170 /* This tries to identify the valid syntaxes for the our
171 * synthetic "gateway" host. */
174 strcaseeq(hostname, "gateway") ||
175 strcaseeq(hostname, "gateway.");
178 int sethostname_idempotent(const char *s) {
179 char buf[HOST_NAME_MAX + 1] = {};
183 if (gethostname(buf, sizeof(buf)) < 0)
189 if (sethostname(s, strlen(s)) < 0)
195 int read_hostname_config(const char *path, char **hostname) {
196 _cleanup_fclose_ FILE *f = NULL;
203 f = fopen(path, "re");
207 /* may have comments, ignore them */
208 FOREACH_LINE(l, f, return -errno) {
210 if (l[0] != '\0' && l[0] != '#') {
211 /* found line with value */
212 name = hostname_cleanup(l);
221 /* no non-empty line found */