mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-24 02:03:54 +03:00
hostname: Allow comments in /etc/hostname
The hostname(1) tool allows comments in /etc/hostname. Introduce a new read_hostname_config() in hostname-util which reads a hostname configuration file like /etc/hostname, strips out comments, whitespace, and cleans the hostname. Use it in hostname-setup.c and hostnamed and remove duplicated code. Update hostname manpage. Add tests. https://launchpad.net/bugs/1053048
This commit is contained in:
parent
e861098bf2
commit
139e533628
@ -57,11 +57,12 @@
|
||||
name of the local system that is set during boot using the
|
||||
<citerefentry><refentrytitle>sethostname</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||
system call. It should contain a single newline-terminated
|
||||
hostname string. The hostname may be a free-form string up to 64
|
||||
characters in length; however, it is recommended that it consists
|
||||
only of 7-bit ASCII lower-case characters and no spaces or dots,
|
||||
and limits itself to the format allowed for DNS domain name
|
||||
labels, even though this is not a strict requirement.</para>
|
||||
hostname string. Comments (lines starting with a `#') are ignored.
|
||||
The hostname may be a free-form string up to 64 characters in length;
|
||||
however, it is recommended that it consists only of 7-bit ASCII lower-case
|
||||
characters and no spaces or dots, and limits itself to the format allowed
|
||||
for DNS domain name labels, even though this is not a strict
|
||||
requirement.</para>
|
||||
|
||||
<para>Depending on the operating system, other configuration files
|
||||
might be checked for configuration of the hostname as well,
|
||||
|
@ -30,35 +30,13 @@
|
||||
#include "hostname-util.h"
|
||||
#include "hostname-setup.h"
|
||||
|
||||
static int read_and_strip_hostname(const char *path, char **hn) {
|
||||
char *s;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
assert(hn);
|
||||
|
||||
r = read_one_line_file(path, &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
hostname_cleanup(s, false);
|
||||
|
||||
if (isempty(s)) {
|
||||
free(s);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
*hn = s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hostname_setup(void) {
|
||||
int r;
|
||||
_cleanup_free_ char *b = NULL;
|
||||
const char *hn;
|
||||
bool enoent = false;
|
||||
|
||||
r = read_and_strip_hostname("/etc/hostname", &b);
|
||||
r = read_hostname_config("/etc/hostname", &b);
|
||||
if (r < 0) {
|
||||
if (r == -ENOENT)
|
||||
enoent = true;
|
||||
|
@ -96,7 +96,7 @@ static int context_read_data(Context *c) {
|
||||
if (!c->data[PROP_HOSTNAME])
|
||||
return -ENOMEM;
|
||||
|
||||
r = read_one_line_file("/etc/hostname", &c->data[PROP_STATIC_HOSTNAME]);
|
||||
r = read_hostname_config("/etc/hostname", &c->data[PROP_STATIC_HOSTNAME]);
|
||||
if (r < 0 && r != -ENOENT)
|
||||
return r;
|
||||
|
||||
|
@ -158,3 +158,36 @@ int sethostname_idempotent(const char *s) {
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int read_hostname_config(const char *path, char **hostname) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
char l[LINE_MAX];
|
||||
char *name = NULL;
|
||||
|
||||
assert(path);
|
||||
assert(hostname);
|
||||
|
||||
f = fopen(path, "re");
|
||||
if (!f)
|
||||
return -errno;
|
||||
|
||||
/* may have comments, ignore them */
|
||||
FOREACH_LINE(l, f, return -errno) {
|
||||
truncate_nl(l);
|
||||
if (l[0] != '\0' && l[0] != '#') {
|
||||
/* found line with value */
|
||||
name = hostname_cleanup(l, false);
|
||||
name = strdup(name);
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!name)
|
||||
/* no non-empty line found */
|
||||
return -ENOENT;
|
||||
|
||||
*hostname = name;
|
||||
return 0;
|
||||
}
|
||||
|
@ -35,3 +35,5 @@ char* hostname_cleanup(char *s, bool lowercase);
|
||||
bool is_localhost(const char *hostname);
|
||||
|
||||
int sethostname_idempotent(const char *s);
|
||||
|
||||
int read_hostname_config(const char *path, char **hostname);
|
||||
|
@ -549,6 +549,52 @@ static void test_hostname_is_valid(void) {
|
||||
assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
|
||||
}
|
||||
|
||||
static void test_read_hostname_config(void) {
|
||||
char path[] = "/tmp/hostname.XXXXXX";
|
||||
char *hostname;
|
||||
int fd;
|
||||
|
||||
fd = mkostemp_safe(path, O_RDWR|O_CLOEXEC);
|
||||
assert(fd > 0);
|
||||
close(fd);
|
||||
|
||||
/* simple hostname */
|
||||
write_string_file(path, "foo");
|
||||
assert_se(read_hostname_config(path, &hostname) == 0);
|
||||
assert_se(streq(hostname, "foo"));
|
||||
free(hostname);
|
||||
|
||||
/* with comment */
|
||||
write_string_file(path, "# comment\nfoo");
|
||||
assert_se(read_hostname_config(path, &hostname) == 0);
|
||||
assert_se(streq(hostname, "foo"));
|
||||
free(hostname);
|
||||
|
||||
/* with comment and extra whitespace */
|
||||
write_string_file(path, "# comment\n\n foo ");
|
||||
assert_se(read_hostname_config(path, &hostname) == 0);
|
||||
assert_se(streq(hostname, "foo"));
|
||||
free(hostname);
|
||||
|
||||
/* cleans up name */
|
||||
write_string_file(path, "!foo/bar.com");
|
||||
assert_se(read_hostname_config(path, &hostname) == 0);
|
||||
assert_se(streq(hostname, "foobar.com"));
|
||||
free(hostname);
|
||||
|
||||
/* no value set */
|
||||
hostname = (char*) 0x1234;
|
||||
write_string_file(path, "# nothing here\n");
|
||||
assert_se(read_hostname_config(path, &hostname) == -ENOENT);
|
||||
assert_se(hostname == (char*) 0x1234); /* does not touch argument on error */
|
||||
|
||||
/* nonexisting file */
|
||||
assert_se(read_hostname_config("/non/existing", &hostname) == -ENOENT);
|
||||
assert_se(hostname == (char*) 0x1234); /* does not touch argument on error */
|
||||
|
||||
unlink(path);
|
||||
}
|
||||
|
||||
static void test_u64log2(void) {
|
||||
assert_se(u64log2(0) == 0);
|
||||
assert_se(u64log2(8) == 3);
|
||||
@ -1481,6 +1527,7 @@ int main(int argc, char *argv[]) {
|
||||
test_foreach_word_quoted();
|
||||
test_memdup_multiply();
|
||||
test_hostname_is_valid();
|
||||
test_read_hostname_config();
|
||||
test_u64log2();
|
||||
test_protect_errno();
|
||||
test_parse_size();
|
||||
|
Loading…
x
Reference in New Issue
Block a user