X Tutup
Skip to content

Commit 0995acc

Browse files
committed
hostname: introduce gethostname_full() and use it in various gethostname() variants
1 parent ccdf235 commit 0995acc

File tree

5 files changed

+65
-79
lines changed

5 files changed

+65
-79
lines changed

src/basic/hostname-util.c

Lines changed: 20 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -36,66 +36,39 @@ char* get_default_hostname(void) {
3636
return strdup(FALLBACK_HOSTNAME);
3737
}
3838

39-
char* gethostname_malloc(void) {
39+
int gethostname_full(GetHostnameFlags flags, char **ret) {
40+
_cleanup_free_ char *buf = NULL, *fallback = NULL;
4041
struct utsname u;
4142
const char *s;
4243

43-
/* This call tries to return something useful, either the actual hostname
44-
* or it makes something up. The only reason it might fail is OOM.
45-
* It might even return "localhost" if that's set. */
44+
assert(ret);
4645

4746
assert_se(uname(&u) >= 0);
4847

4948
s = u.nodename;
50-
if (isempty(s) || streq(s, "(none)"))
51-
return get_default_hostname();
52-
53-
return strdup(s);
54-
}
55-
56-
char* gethostname_short_malloc(void) {
57-
struct utsname u;
58-
const char *s;
59-
_cleanup_free_ char *f = NULL;
60-
61-
/* Like above, but kills the FQDN part if present. */
62-
63-
assert_se(uname(&u) >= 0);
64-
65-
s = u.nodename;
66-
if (isempty(s) || streq(s, "(none)") || s[0] == '.') {
67-
s = f = get_default_hostname();
49+
if (isempty(s) ||
50+
(!FLAGS_SET(flags, GET_HOSTNAME_ALLOW_NONE) && streq(s, "(none)")) ||
51+
(!FLAGS_SET(flags, GET_HOSTNAME_ALLOW_LOCALHOST) && is_localhost(s)) ||
52+
(FLAGS_SET(flags, GET_HOSTNAME_SHORT) && s[0] == '.')) {
53+
if (!FLAGS_SET(flags, GET_HOSTNAME_FALLBACK_DEFAULT))
54+
return -ENXIO;
55+
56+
s = fallback = get_default_hostname();
6857
if (!s)
69-
return NULL;
58+
return -ENOMEM;
7059

71-
assert(s[0] != '.');
60+
if (FLAGS_SET(flags, GET_HOSTNAME_SHORT) && s[0] == '.')
61+
return -ENXIO;
7262
}
7363

74-
return strndup(s, strcspn(s, "."));
75-
}
76-
77-
int gethostname_strict(char **ret) {
78-
struct utsname u;
79-
char *k;
80-
81-
/* This call will rather fail than make up a name. It will not return "localhost" either. */
82-
83-
assert_se(uname(&u) >= 0);
84-
85-
if (isempty(u.nodename))
86-
return -ENXIO;
87-
88-
if (streq(u.nodename, "(none)"))
89-
return -ENXIO;
90-
91-
if (is_localhost(u.nodename))
92-
return -ENXIO;
93-
94-
k = strdup(u.nodename);
95-
if (!k)
64+
if (FLAGS_SET(flags, GET_HOSTNAME_SHORT))
65+
buf = strndup(s, strcspn(s, "."));
66+
else
67+
buf = strdup(s);
68+
if (!buf)
9669
return -ENOMEM;
9770

98-
*ret = k;
71+
*ret = TAKE_PTR(buf);
9972
return 0;
10073
}
10174

src/basic/hostname-util.h

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,37 @@
77
#include "macro.h"
88
#include "strv.h"
99

10+
typedef enum GetHostnameFlags {
11+
GET_HOSTNAME_ALLOW_NONE = 1 << 0, /* accepts "(none)". */
12+
GET_HOSTNAME_ALLOW_LOCALHOST = 1 << 1, /* accepts "localhost" or friends. */
13+
GET_HOSTNAME_FALLBACK_DEFAULT = 1 << 2, /* use default hostname if no hostname is set. */
14+
GET_HOSTNAME_SHORT = 1 << 3, /* kills the FQDN part if present. */
15+
} GetHostnameFlags;
16+
17+
int gethostname_full(GetHostnameFlags flags, char **ret);
18+
static inline int gethostname_strict(char **ret) {
19+
return gethostname_full(0, ret);
20+
}
21+
22+
static inline char* gethostname_malloc(void) {
23+
char *s;
24+
25+
if (gethostname_full(GET_HOSTNAME_ALLOW_LOCALHOST | GET_HOSTNAME_FALLBACK_DEFAULT, &s) < 0)
26+
return NULL;
27+
28+
return s;
29+
}
30+
31+
static inline char* gethostname_short_malloc(void) {
32+
char *s;
33+
34+
if (gethostname_full(GET_HOSTNAME_ALLOW_LOCALHOST | GET_HOSTNAME_FALLBACK_DEFAULT | GET_HOSTNAME_SHORT, &s) < 0)
35+
return NULL;
36+
37+
return s;
38+
}
39+
1040
char* get_default_hostname(void);
11-
char* gethostname_malloc(void);
12-
char* gethostname_short_malloc(void);
13-
int gethostname_strict(char **ret);
1441

1542
bool valid_ldh_char(char c) _const_;
1643

src/hostname/hostnamed.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -575,20 +575,21 @@ static int property_get_default_hostname(
575575
}
576576

577577
static void context_determine_hostname_source(Context *c) {
578-
char hostname[HOST_NAME_MAX + 1] = {};
579-
_cleanup_free_ char *fallback = NULL;
578+
_cleanup_free_ char *hostname = NULL;
580579
int r;
581580

582581
assert(c);
583582

584583
if (c->hostname_source >= 0)
585584
return;
586585

587-
(void) get_hostname_filtered(hostname);
586+
(void) gethostname_full(GET_HOSTNAME_ALLOW_LOCALHOST, &hostname);
588587

589588
if (streq_ptr(hostname, c->data[PROP_STATIC_HOSTNAME]))
590589
c->hostname_source = HOSTNAME_STATIC;
591590
else {
591+
_cleanup_free_ char *fallback = NULL;
592+
592593
/* If the hostname was not set by us, try to figure out where it came from. If we set it to
593594
* the default hostname, the file will tell us. We compare the string because it is possible
594595
* that the hostname was set by an older version that had a different fallback, in the

src/shared/hostname-setup.c

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@
2020
#include "util.h"
2121

2222
static int sethostname_idempotent_full(const char *s, bool really) {
23-
char buf[HOST_NAME_MAX + 1];
23+
_cleanup_free_ char *buf = NULL;
24+
int r;
2425

2526
assert(s);
2627

27-
if (gethostname(buf, sizeof(buf)) < 0)
28-
return -errno;
28+
r = gethostname_full(GET_HOSTNAME_ALLOW_NONE | GET_HOSTNAME_ALLOW_LOCALHOST, &buf);
29+
if (r < 0)
30+
return r;
2931

3032
if (streq(buf, s))
3133
return 0;
@@ -41,26 +43,6 @@ int sethostname_idempotent(const char *s) {
4143
return sethostname_idempotent_full(s, true);
4244
}
4345

44-
bool get_hostname_filtered(char ret[static HOST_NAME_MAX + 1]) {
45-
char buf[HOST_NAME_MAX + 1];
46-
47-
/* Returns true if we got a good hostname, false otherwise. */
48-
49-
if (gethostname(buf, sizeof(buf)) < 0)
50-
return false; /* This can realistically only fail with ENAMETOOLONG.
51-
* Let's treat that case the same as an invalid hostname. */
52-
53-
if (isempty(buf))
54-
return false;
55-
56-
/* This is the built-in kernel default hostname */
57-
if (streq(buf, "(none)"))
58-
return false;
59-
60-
memcpy(ret, buf, sizeof buf);
61-
return true;
62-
}
63-
6446
int shorten_overlong(const char *s, char **ret) {
6547
char *h, *p;
6648

@@ -195,10 +177,14 @@ int hostname_setup(bool really) {
195177
}
196178

197179
if (!hn) {
180+
_cleanup_free_ char *buf = NULL;
181+
198182
/* Don't override the hostname if it is already set and not explicitly configured */
199183

200-
char buf[HOST_NAME_MAX + 1] = {};
201-
if (get_hostname_filtered(buf)) {
184+
r = gethostname_full(GET_HOSTNAME_ALLOW_LOCALHOST, &buf);
185+
if (r == -ENOMEM)
186+
return log_oom();
187+
if (r >= 0) {
202188
log_debug("No hostname configured, leaving existing hostname <%s> in place.", buf);
203189
return 0;
204190
}

src/shared/hostname-setup.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,5 @@ int shorten_overlong(const char *s, char **ret);
2121
int read_etc_hostname_stream(FILE *f, char **ret);
2222
int read_etc_hostname(const char *path, char **ret);
2323

24-
bool get_hostname_filtered(char ret[static HOST_NAME_MAX + 1]);
2524
void hostname_update_source_hint(const char *hostname, HostnameSource source);
2625
int hostname_setup(bool really);

0 commit comments

Comments
 (0)
X Tutup