return strdup(FALLBACK_HOSTNAME);
}
-char* gethostname_malloc(void) {
+int gethostname_full(GetHostnameFlags flags, char **ret) {
+ _cleanup_free_ char *buf = NULL, *fallback = NULL;
struct utsname u;
const char *s;
- /* This call tries to return something useful, either the actual hostname
- * or it makes something up. The only reason it might fail is OOM.
- * It might even return "localhost" if that's set. */
+ assert(ret);
assert_se(uname(&u) >= 0);
s = u.nodename;
- if (isempty(s) || streq(s, "(none)"))
- return get_default_hostname();
-
- return strdup(s);
-}
-
-char* gethostname_short_malloc(void) {
- struct utsname u;
- const char *s;
- _cleanup_free_ char *f = NULL;
-
- /* Like above, but kills the FQDN part if present. */
-
- assert_se(uname(&u) >= 0);
-
- s = u.nodename;
- if (isempty(s) || streq(s, "(none)") || s[0] == '.') {
- s = f = get_default_hostname();
+ if (isempty(s) ||
+ (!FLAGS_SET(flags, GET_HOSTNAME_ALLOW_NONE) && streq(s, "(none)")) ||
+ (!FLAGS_SET(flags, GET_HOSTNAME_ALLOW_LOCALHOST) && is_localhost(s)) ||
+ (FLAGS_SET(flags, GET_HOSTNAME_SHORT) && s[0] == '.')) {
+ if (!FLAGS_SET(flags, GET_HOSTNAME_FALLBACK_DEFAULT))
+ return -ENXIO;
+
+ s = fallback = get_default_hostname();
if (!s)
- return NULL;
+ return -ENOMEM;
- assert(s[0] != '.');
+ if (FLAGS_SET(flags, GET_HOSTNAME_SHORT) && s[0] == '.')
+ return -ENXIO;
}
- return strndup(s, strcspn(s, "."));
-}
-
-int gethostname_strict(char **ret) {
- struct utsname u;
- char *k;
-
- /* This call will rather fail than make up a name. It will not return "localhost" either. */
-
- assert_se(uname(&u) >= 0);
-
- if (isempty(u.nodename))
- return -ENXIO;
-
- if (streq(u.nodename, "(none)"))
- return -ENXIO;
-
- if (is_localhost(u.nodename))
- return -ENXIO;
-
- k = strdup(u.nodename);
- if (!k)
+ if (FLAGS_SET(flags, GET_HOSTNAME_SHORT))
+ buf = strndup(s, strcspn(s, "."));
+ else
+ buf = strdup(s);
+ if (!buf)
return -ENOMEM;
- *ret = k;
+ *ret = TAKE_PTR(buf);
return 0;
}
#include "macro.h"
#include "strv.h"
+typedef enum GetHostnameFlags {
+ GET_HOSTNAME_ALLOW_NONE = 1 << 0, /* accepts "(none)". */
+ GET_HOSTNAME_ALLOW_LOCALHOST = 1 << 1, /* accepts "localhost" or friends. */
+ GET_HOSTNAME_FALLBACK_DEFAULT = 1 << 2, /* use default hostname if no hostname is set. */
+ GET_HOSTNAME_SHORT = 1 << 3, /* kills the FQDN part if present. */
+} GetHostnameFlags;
+
+int gethostname_full(GetHostnameFlags flags, char **ret);
+static inline int gethostname_strict(char **ret) {
+ return gethostname_full(0, ret);
+}
+
+static inline char* gethostname_malloc(void) {
+ char *s;
+
+ if (gethostname_full(GET_HOSTNAME_ALLOW_LOCALHOST | GET_HOSTNAME_FALLBACK_DEFAULT, &s) < 0)
+ return NULL;
+
+ return s;
+}
+
+static inline char* gethostname_short_malloc(void) {
+ char *s;
+
+ if (gethostname_full(GET_HOSTNAME_ALLOW_LOCALHOST | GET_HOSTNAME_FALLBACK_DEFAULT | GET_HOSTNAME_SHORT, &s) < 0)
+ return NULL;
+
+ return s;
+}
+
char* get_default_hostname(void);
-char* gethostname_malloc(void);
-char* gethostname_short_malloc(void);
-int gethostname_strict(char **ret);
bool valid_ldh_char(char c) _const_;
}
static void context_determine_hostname_source(Context *c) {
- char hostname[HOST_NAME_MAX + 1] = {};
- _cleanup_free_ char *fallback = NULL;
+ _cleanup_free_ char *hostname = NULL;
int r;
assert(c);
if (c->hostname_source >= 0)
return;
- (void) get_hostname_filtered(hostname);
+ (void) gethostname_full(GET_HOSTNAME_ALLOW_LOCALHOST, &hostname);
if (streq_ptr(hostname, c->data[PROP_STATIC_HOSTNAME]))
c->hostname_source = HOSTNAME_STATIC;
else {
+ _cleanup_free_ char *fallback = NULL;
+
/* If the hostname was not set by us, try to figure out where it came from. If we set it to
* the default hostname, the file will tell us. We compare the string because it is possible
* that the hostname was set by an older version that had a different fallback, in the
#include "util.h"
static int sethostname_idempotent_full(const char *s, bool really) {
- char buf[HOST_NAME_MAX + 1];
+ _cleanup_free_ char *buf = NULL;
+ int r;
assert(s);
- if (gethostname(buf, sizeof(buf)) < 0)
- return -errno;
+ r = gethostname_full(GET_HOSTNAME_ALLOW_NONE | GET_HOSTNAME_ALLOW_LOCALHOST, &buf);
+ if (r < 0)
+ return r;
if (streq(buf, s))
return 0;
return sethostname_idempotent_full(s, true);
}
-bool get_hostname_filtered(char ret[static HOST_NAME_MAX + 1]) {
- char buf[HOST_NAME_MAX + 1];
-
- /* Returns true if we got a good hostname, false otherwise. */
-
- if (gethostname(buf, sizeof(buf)) < 0)
- return false; /* This can realistically only fail with ENAMETOOLONG.
- * Let's treat that case the same as an invalid hostname. */
-
- if (isempty(buf))
- return false;
-
- /* This is the built-in kernel default hostname */
- if (streq(buf, "(none)"))
- return false;
-
- memcpy(ret, buf, sizeof buf);
- return true;
-}
-
int shorten_overlong(const char *s, char **ret) {
char *h, *p;
}
if (!hn) {
+ _cleanup_free_ char *buf = NULL;
+
/* Don't override the hostname if it is already set and not explicitly configured */
- char buf[HOST_NAME_MAX + 1] = {};
- if (get_hostname_filtered(buf)) {
+ r = gethostname_full(GET_HOSTNAME_ALLOW_LOCALHOST, &buf);
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r >= 0) {
log_debug("No hostname configured, leaving existing hostname <%s> in place.", buf);
return 0;
}
int read_etc_hostname_stream(FILE *f, char **ret);
int read_etc_hostname(const char *path, char **ret);
-bool get_hostname_filtered(char ret[static HOST_NAME_MAX + 1]);
void hostname_update_source_hint(const char *hostname, HostnameSource source);
int hostname_setup(bool really);