]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/hostname-util.c
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>
29 #include "hostname-util.h"
31 #include "string-util.h"
33 bool hostname_is_set(void) {
36 assert_se(uname(&u
) >= 0);
38 if (isempty(u
.nodename
))
41 /* This is the built-in kernel default host name */
42 if (streq(u
.nodename
, "(none)"))
48 char* gethostname_malloc(void) {
51 assert_se(uname(&u
) >= 0);
53 if (isempty(u
.nodename
) || streq(u
.nodename
, "(none)"))
54 return strdup(u
.sysname
);
56 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 char* hostname_cleanup(char *s
) {
124 for (p
= s
, d
= s
, dot
= true; *p
; p
++) {
131 } else if (hostname_valid_char(*p
)) {
143 strshorten(s
, HOST_NAME_MAX
);
148 bool is_localhost(const char *hostname
) {
151 /* This tries to identify local host and domain names
152 * described in RFC6761 plus the redhatism of .localdomain */
154 return strcaseeq(hostname
, "localhost") ||
155 strcaseeq(hostname
, "localhost.") ||
156 strcaseeq(hostname
, "localdomain.") ||
157 strcaseeq(hostname
, "localdomain") ||
158 endswith_no_case(hostname
, ".localhost") ||
159 endswith_no_case(hostname
, ".localhost.") ||
160 endswith_no_case(hostname
, ".localdomain") ||
161 endswith_no_case(hostname
, ".localdomain.");
164 bool is_gateway_hostname(const char *hostname
) {
167 /* This tries to identify the valid syntaxes for the our
168 * synthetic "gateway" host. */
171 strcaseeq(hostname
, "gateway") ||
172 strcaseeq(hostname
, "gateway.");
175 int sethostname_idempotent(const char *s
) {
176 char buf
[HOST_NAME_MAX
+ 1] = {};
180 if (gethostname(buf
, sizeof(buf
)) < 0)
186 if (sethostname(s
, strlen(s
)) < 0)
192 int read_hostname_config(const char *path
, char **hostname
) {
193 _cleanup_fclose_
FILE *f
= NULL
;
200 f
= fopen(path
, "re");
204 /* may have comments, ignore them */
205 FOREACH_LINE(l
, f
, return -errno
) {
207 if (l
[0] != '\0' && l
[0] != '#') {
208 /* found line with value */
209 name
= hostname_cleanup(l
);
218 /* no non-empty line found */