]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/hostname-util.c
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 bool hostname_is_set(void) {
31 assert_se(uname(&u
) >= 0);
33 if (isempty(u
.nodename
))
36 /* This is the built-in kernel default host name */
37 if (streq(u
.nodename
, "(none)"))
43 char* gethostname_malloc(void) {
46 assert_se(uname(&u
) >= 0);
48 if (isempty(u
.nodename
) || streq(u
.nodename
, "(none)"))
49 return strdup(u
.sysname
);
51 return strdup(u
.nodename
);
54 static bool hostname_valid_char(char c
) {
56 (c
>= 'a' && c
<= 'z') ||
57 (c
>= 'A' && c
<= 'Z') ||
58 (c
>= '0' && c
<= '9') ||
65 * Check if s looks like a valid host name or fqdn. This does not do
66 * full DNS validation, but only checks if the name is composed of
67 * allowed characters and the length is not above the maximum allowed
68 * by Linux (c.f. dns_name_is_valid()). Trailing dot is allowed if
69 * relax is true and at least two components are present in the name.
71 bool hostname_is_valid(const char *s
, bool relax
) {
79 /* Doesn't accept empty hostnames, hostnames with
80 * leading dots, and hostnames with multiple dots in a
81 * sequence. Also ensures that the length stays below
84 for (p
= s
, dot
= true; *p
; p
++) {
92 if (!hostname_valid_char(*p
))
99 if (dot
&& (dots
< 2 || !relax
))
102 if (p
-s
> HOST_NAME_MAX
)
108 char* hostname_cleanup(char *s
) {
114 for (p
= s
, d
= s
, dot
= true; *p
; p
++) {
121 } else if (hostname_valid_char(*p
)) {
133 strshorten(s
, HOST_NAME_MAX
);
138 bool is_localhost(const char *hostname
) {
141 /* This tries to identify local host and domain names
142 * described in RFC6761 plus the redhatism of .localdomain */
144 return streq(hostname
, "localhost") ||
145 streq(hostname
, "localhost.") ||
146 streq(hostname
, "localdomain.") ||
147 streq(hostname
, "localdomain") ||
148 endswith(hostname
, ".localhost") ||
149 endswith(hostname
, ".localhost.") ||
150 endswith(hostname
, ".localdomain") ||
151 endswith(hostname
, ".localdomain.");
154 int sethostname_idempotent(const char *s
) {
155 char buf
[HOST_NAME_MAX
+ 1] = {};
159 if (gethostname(buf
, sizeof(buf
)) < 0)
165 if (sethostname(s
, strlen(s
)) < 0)
171 int read_hostname_config(const char *path
, char **hostname
) {
172 _cleanup_fclose_
FILE *f
= NULL
;
179 f
= fopen(path
, "re");
183 /* may have comments, ignore them */
184 FOREACH_LINE(l
, f
, return -errno
) {
186 if (l
[0] != '\0' && l
[0] != '#') {
187 /* found line with value */
188 name
= hostname_cleanup(l
);
197 /* no non-empty line found */