]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
hostname: Allow comments in /etc/hostname
authorMartin Pitt <martin.pitt@ubuntu.com>
Tue, 19 May 2015 05:49:56 +0000 (07:49 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 19 May 2015 10:18:08 +0000 (12:18 +0200)
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

man/hostname.xml
src/core/hostname-setup.c
src/hostname/hostnamed.c
src/shared/hostname-util.c
src/shared/hostname-util.h
src/test/test-util.c

index 5d3d46d8cef5bf829a0fbe8bfb0ddfe4163089eb..9688450e1c2bf8180802d2c4ee4a7fb2a9489e35 100644 (file)
     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,
index 217f201d0520e481626962aea6d533301d7b0b96..932ddbf95a96147d28f2ef1c8023cf2695ad4210 100644 (file)
 #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;
index ab9ddc706acea45c972df20651b2fb788ef6c161..7ff3a4e224142a08467067e804d0d0794273ca33 100644 (file)
@@ -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;
 
index 2998fdf2c7328db18b033027d53ebb145fec6a0b..e336f269fae160cf4c045f1b34b1719ee278b353 100644 (file)
@@ -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;
+}
index f2821c307810f8156567d38f837310c9bb856b1b..0c4763cf5a377053b085a272e04cce85607b082d 100644 (file)
@@ -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);
index 9af3e757e3de520e7da50a0653fd45e079035492..36773c109da2d367f8a1dc01120446cd2baceb4c 100644 (file)
@@ -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();