[systemd-commits] 2 commits - src/firstboot src/journal src/shared src/sysusers src/test src/tmpfiles

Lennart Poettering lennart at kemper.freedesktop.org
Wed May 13 08:58:46 PDT 2015


 src/firstboot/firstboot.c |   18 ++++++++----------
 src/journal/journal-def.h |    2 +-
 src/shared/conf-files.c   |    6 +++---
 src/shared/path-util.c    |   34 ++++++++++++++++++++++++++++++++++
 src/shared/path-util.h    |   27 +++++++++++++++++++++++++++
 src/sysusers/sysusers.c   |   16 +++++++---------
 src/test/test-path-util.c |   29 +++++++++++++++++++++++++++++
 src/tmpfiles/tmpfiles.c   |    2 +-
 8 files changed, 110 insertions(+), 24 deletions(-)

New commits:
commit b4a855e9f6a4d09c18772aa797dc7d606d163b88
Author: Peter Lemenkov <lemenkov at gmail.com>
Date:   Tue May 12 14:45:33 2015 +0300

    journal: fix size comment
    
    Looks like sizeof(struct Header) is 240 not 224

diff --git a/src/journal/journal-def.h b/src/journal/journal-def.h
index ab089cb..39c9dd0 100644
--- a/src/journal/journal-def.h
+++ b/src/journal/journal-def.h
@@ -220,7 +220,7 @@ struct Header {
         le64_t n_tags;
         le64_t n_entry_arrays;
 
-        /* Size: 224 */
+        /* Size: 240 */
 } _packed_;
 
 #define FSS_HEADER_SIGNATURE ((char[]) { 'K', 'S', 'H', 'H', 'R', 'H', 'L', 'P' })

commit 1d13f648d0fade38194db74b4f82ca68c8a26856
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed May 13 17:42:10 2015 +0200

    util: add generic calls for prefixing a root directory to a path
    
    So far a number of utilities implemented their own calls for this, unify
    them in prefix_root() and prefix_roota(). The former uses heap memory,
    the latter allocates from the stack via alloca().
    
    Port over most users of a --root= logic.

diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c
index 37326df..d156d57 100644
--- a/src/firstboot/firstboot.c
+++ b/src/firstboot/firstboot.c
@@ -52,8 +52,6 @@ static bool arg_copy_locale = false;
 static bool arg_copy_timezone = false;
 static bool arg_copy_root_password = false;
 
-#define prefix_roota(p) (arg_root ? (const char*) strjoina(arg_root, p) : (const char*) p)
-
 static void clear_string(char *x) {
 
         if (!x)
@@ -87,13 +85,13 @@ static void print_welcome(void) {
         if (done)
                 return;
 
-        os_release = prefix_roota("/etc/os-release");
+        os_release = prefix_roota(arg_root, "/etc/os-release");
         r = parse_env_file(os_release, NEWLINE,
                            "PRETTY_NAME", &pretty_name,
                            NULL);
         if (r == -ENOENT) {
 
-                os_release = prefix_roota("/usr/lib/os-release");
+                os_release = prefix_roota(arg_root, "/usr/lib/os-release");
                 r = parse_env_file(os_release, NEWLINE,
                                    "PRETTY_NAME", &pretty_name,
                                    NULL);
@@ -251,7 +249,7 @@ static int process_locale(void) {
         unsigned i = 0;
         int r;
 
-        etc_localeconf = prefix_roota("/etc/locale.conf");
+        etc_localeconf = prefix_roota(arg_root, "/etc/locale.conf");
         if (faccessat(AT_FDCWD, etc_localeconf, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
                 return 0;
 
@@ -325,7 +323,7 @@ static int process_timezone(void) {
         const char *etc_localtime, *e;
         int r;
 
-        etc_localtime = prefix_roota("/etc/localtime");
+        etc_localtime = prefix_roota(arg_root, "/etc/localtime");
         if (faccessat(AT_FDCWD, etc_localtime, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
                 return 0;
 
@@ -404,7 +402,7 @@ static int process_hostname(void) {
         const char *etc_hostname;
         int r;
 
-        etc_hostname = prefix_roota("/etc/hostname");
+        etc_hostname = prefix_roota(arg_root, "/etc/hostname");
         if (faccessat(AT_FDCWD, etc_hostname, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
                 return 0;
 
@@ -429,7 +427,7 @@ static int process_machine_id(void) {
         char id[SD_ID128_STRING_MAX];
         int r;
 
-        etc_machine_id = prefix_roota("/etc/machine-id");
+        etc_machine_id = prefix_roota(arg_root, "/etc/machine-id");
         if (faccessat(AT_FDCWD, etc_machine_id, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
                 return 0;
 
@@ -455,7 +453,7 @@ static int prompt_root_password(void) {
         if (!arg_prompt_root_password)
                 return 0;
 
-        etc_shadow = prefix_roota("/etc/shadow");
+        etc_shadow = prefix_roota(arg_root, "/etc/shadow");
         if (faccessat(AT_FDCWD, etc_shadow, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
                 return 0;
 
@@ -544,7 +542,7 @@ static int process_root_password(void) {
         const char *etc_shadow;
         int r;
 
-        etc_shadow = prefix_roota("/etc/shadow");
+        etc_shadow = prefix_roota(arg_root, "/etc/shadow");
         if (faccessat(AT_FDCWD, etc_shadow, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
                 return 0;
 
diff --git a/src/shared/conf-files.c b/src/shared/conf-files.c
index 9ab0835..da8745b 100644
--- a/src/shared/conf-files.c
+++ b/src/shared/conf-files.c
@@ -36,12 +36,13 @@
 
 static int files_add(Hashmap *h, const char *root, const char *path, const char *suffix) {
         _cleanup_closedir_ DIR *dir = NULL;
-        char *dirpath;
+        const char *dirpath;
+        int r;
 
         assert(path);
         assert(suffix);
 
-        dirpath = strjoina(root ? root : "", path);
+        dirpath = prefix_roota(root, path);
 
         dir = opendir(dirpath);
         if (!dir) {
@@ -53,7 +54,6 @@ static int files_add(Hashmap *h, const char *root, const char *path, const char
         for (;;) {
                 struct dirent *de;
                 char *p;
-                int r;
 
                 errno = 0;
                 de = readdir(dir);
diff --git a/src/shared/path-util.c b/src/shared/path-util.c
index 635ce33..7090989 100644
--- a/src/shared/path-util.c
+++ b/src/shared/path-util.c
@@ -793,3 +793,37 @@ int fsck_exists(const char *fstype) {
 
         return 0;
 }
+
+char *prefix_root(const char *root, const char *path) {
+        char *n, *p;
+        size_t l;
+
+        /* If root is passed, prefixes path with it. Otherwise returns
+         * it as is. */
+
+        assert(path);
+
+        /* First, drop duplicate prefixing slashes from the path */
+        while (path[0] == '/' && path[1] == '/')
+                path++;
+
+        if (isempty(root) || path_equal(root, "/"))
+                return strdup(path);
+
+        l = strlen(root) + 1 + strlen(path) + 1;
+
+        n = new(char, l);
+        if (!n)
+                return NULL;
+
+        p = stpcpy(n, root);
+
+        while (p > n && p[-1] == '/')
+                p--;
+
+        if (path[0] != '/')
+                *(p++) = '/';
+
+        strcpy(p, path);
+        return n;
+}
diff --git a/src/shared/path-util.h b/src/shared/path-util.h
index 5548ce4..4f45cfd 100644
--- a/src/shared/path-util.h
+++ b/src/shared/path-util.h
@@ -73,3 +73,30 @@ int fsck_exists(const char *fstype);
 /* Same as PATH_FOREACH_PREFIX but also includes the specified path itself */
 #define PATH_FOREACH_PREFIX_MORE(prefix, path) \
         for (char *_slash = ({ path_kill_slashes(strcpy(prefix, path)); if (streq(prefix, "/")) prefix[0] = 0; strrchr(prefix, 0); }); _slash && ((*_slash = 0), true); _slash = strrchr((prefix), '/'))
+
+char *prefix_root(const char *root, const char *path);
+
+/* Similar to prefix_root(), but returns an alloca() buffer, or
+ * possibly a const pointer into the path parameter */
+#define prefix_roota(root, path)                                        \
+        ({                                                              \
+                const char* _path = (path), *_root = (root), *_ret;     \
+                char *_p, *_n;                                          \
+                size_t _l;                                              \
+                while (_path[0] == '/' && _path[1] == '/')              \
+                        _path ++;                                       \
+                if (isempty(_root) || path_equal(_root, "/"))           \
+                        _ret = _path;                                   \
+                else {                                                  \
+                        _l = strlen(_root) + 1 + strlen(_path) + 1;     \
+                        _n = alloca(_l);                                \
+                        _p = stpcpy(_n, _root);                         \
+                        while (_p > _n && _p[-1] == '/')                \
+                                _p--;                                   \
+                        if (_path[0] != '/')                            \
+                                *(_p++) = '/';                          \
+                        strcpy(_p, _path);                              \
+                        _ret = _n;                                      \
+                }                                                       \
+                _ret;                                                   \
+        })
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index cc4c7ef..d7ba482 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -80,15 +80,13 @@ static uid_t search_uid = UID_INVALID;
 static UidRange *uid_range = NULL;
 static unsigned n_uid_range = 0;
 
-#define fix_root(x) (arg_root ? strjoina(arg_root, x) : x)
-
 static int load_user_database(void) {
         _cleanup_fclose_ FILE *f = NULL;
         const char *passwd_path;
         struct passwd *pw;
         int r;
 
-        passwd_path = fix_root("/etc/passwd");
+        passwd_path = prefix_roota(arg_root, "/etc/passwd");
         f = fopen(passwd_path, "re");
         if (!f)
                 return errno == ENOENT ? 0 : -errno;
@@ -140,7 +138,7 @@ static int load_group_database(void) {
         struct group *gr;
         int r;
 
-        group_path = fix_root("/etc/group");
+        group_path = prefix_roota(arg_root, "/etc/group");
         f = fopen(group_path, "re");
         if (!f)
                 return errno == ENOENT ? 0 : -errno;
@@ -369,7 +367,7 @@ static int write_files(void) {
                 _cleanup_fclose_ FILE *original = NULL;
 
                 /* First we update the actual group list file */
-                group_path = fix_root("/etc/group");
+                group_path = prefix_roota(arg_root, "/etc/group");
                 r = fopen_temporary_label("/etc/group", group_path, &group, &group_tmp);
                 if (r < 0)
                         goto finish;
@@ -448,7 +446,7 @@ static int write_files(void) {
                 }
 
                 /* OK, now also update the shadow file for the group list */
-                gshadow_path = fix_root("/etc/gshadow");
+                gshadow_path = prefix_roota(arg_root, "/etc/gshadow");
                 r = fopen_temporary_label("/etc/gshadow", gshadow_path, &gshadow, &gshadow_tmp);
                 if (r < 0)
                         goto finish;
@@ -514,7 +512,7 @@ static int write_files(void) {
                 long lstchg;
 
                 /* First we update the user database itself */
-                passwd_path = fix_root("/etc/passwd");
+                passwd_path = prefix_roota(arg_root, "/etc/passwd");
                 r = fopen_temporary_label("/etc/passwd", passwd_path, &passwd, &passwd_tmp);
                 if (r < 0)
                         goto finish;
@@ -599,7 +597,7 @@ static int write_files(void) {
                 }
 
                 /* The we update the shadow database */
-                shadow_path = fix_root("/etc/shadow");
+                shadow_path = prefix_roota(arg_root, "/etc/shadow");
                 r = fopen_temporary_label("/etc/shadow", shadow_path, &shadow, &shadow_tmp);
                 if (r < 0)
                         goto finish;
@@ -802,7 +800,7 @@ static int uid_is_ok(uid_t uid, const char *name) {
 static int root_stat(const char *p, struct stat *st) {
         const char *fix;
 
-        fix = fix_root(p);
+        fix = prefix_roota(arg_root, p);
         if (stat(fix, st) < 0)
                 return -errno;
 
diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c
index e5b9c28..09f0f2f 100644
--- a/src/test/test-path-util.c
+++ b/src/test/test-path-util.c
@@ -294,6 +294,34 @@ static void test_path_startswith(void) {
         assert_se(!path_startswith("/foo/bar/barfoo/", "/f/b/b/"));
 }
 
+static void test_prefix_root_one(const char *r, const char *p, const char *expected) {
+        _cleanup_free_ char *s = NULL;
+        const char *t;
+
+        assert_se(s = prefix_root(r, p));
+        assert_se(streq_ptr(s, expected));
+
+        t = prefix_roota(r, p);
+        assert_se(t);
+        assert_se(streq_ptr(t, expected));
+}
+
+static void test_prefix_root(void) {
+        test_prefix_root_one("/", "/foo", "/foo");
+        test_prefix_root_one(NULL, "/foo", "/foo");
+        test_prefix_root_one("", "/foo", "/foo");
+        test_prefix_root_one("///", "/foo", "/foo");
+        test_prefix_root_one("/", "////foo", "/foo");
+        test_prefix_root_one(NULL, "////foo", "/foo");
+
+        test_prefix_root_one("/foo", "/bar", "/foo/bar");
+        test_prefix_root_one("/foo", "bar", "/foo/bar");
+        test_prefix_root_one("foo", "bar", "foo/bar");
+        test_prefix_root_one("/foo/", "/bar", "/foo/bar");
+        test_prefix_root_one("/foo/", "//bar", "/foo/bar");
+        test_prefix_root_one("/foo///", "//bar", "/foo/bar");
+}
+
 int main(int argc, char **argv) {
         test_path();
         test_find_binary(argv[0], true);
@@ -304,6 +332,7 @@ int main(int argc, char **argv) {
         test_make_relative();
         test_strv_resolve();
         test_path_startswith();
+        test_prefix_root();
 
         return 0;
 }
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index 640ad47..5a57835 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -1926,7 +1926,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
         if (arg_root) {
                 char *p;
 
-                p = strappend(arg_root, i.path);
+                p = prefix_root(arg_root, i.path);
                 if (!p)
                         return log_oom();
 



More information about the systemd-commits mailing list