chiark / gitweb /
fs-util: add flags parameter to chase_symlinks()
authorLennart Poettering <lennart@poettering.net>
Tue, 29 Nov 2016 15:49:30 +0000 (16:49 +0100)
committerSven Eden <yamakuzure@gmx.net>
Mon, 17 Jul 2017 15:58:35 +0000 (17:58 +0200)
Let's remove chase_symlinks_prefix() and instead introduce a flags parameter to
chase_symlinks(), with a flag CHASE_PREFIX_ROOT that exposes the behaviour of
chase_symlinks_prefix().

src/basic/fs-util.c
src/basic/fs-util.h
src/basic/mount-util.c
src/basic/path-util.c

index b97edb552c067c7b10b0c805e3aa7ccd8e2efad1..e47b050b0dd95c0239d89a8fa39fadeca845cf94 100644 (file)
@@ -236,7 +236,7 @@ int readlink_and_canonicalize(const char *p, const char *root, char **ret) {
         if (r < 0)
                 return r;
 
-        r = chase_symlinks(t, root, &s);
+        r = chase_symlinks(t, root, 0, &s);
         if (r < 0)
                 /* If we can't follow up, then let's return the original string, slightly cleaned up. */
                 *ret = path_kill_slashes(t);
@@ -603,7 +603,7 @@ int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
         return r;
 }
 
-int chase_symlinks(const char *path, const char *_root, char **ret) {
+int chase_symlinks(const char *path, const char *original_root, unsigned flags, char **ret) {
         _cleanup_free_ char *buffer = NULL, *done = NULL, *root = NULL;
         _cleanup_close_ int fd = -1;
         unsigned max_follow = 32; /* how many symlinks to follow before giving up and returning ELOOP */
@@ -616,8 +616,9 @@ int chase_symlinks(const char *path, const char *_root, char **ret) {
          * symlinks relative to a root directory, instead of the root of the host.
          *
          * Note that "root" primarily matters if we encounter an absolute symlink. It is also used when following
-         * relative symlinks to ensure they cannot be used to "escape" the root directory. The path parameter passed
-         * shall *not* be prefixed by it.
+         * relative symlinks to ensure they cannot be used to "escape" the root directory. The path parameter passed is
+         * assumed to be already prefixed by it, except if the CHASE_PREFIX_ROOT flag is set, in which case it is first
+         * prefixed accordingly.
          *
          * Algorithmically this operates on two path buffers: "done" are the components of the path we already
          * processed and resolved symlinks, "." and ".." of. "todo" are the components of the path we still need to
@@ -634,16 +635,19 @@ int chase_symlinks(const char *path, const char *_root, char **ret) {
          * Note: there's also chase_symlinks_prefix() (see below), which as first step prefixes the passed path by the
          * passed root. */
 
-        r = path_make_absolute_cwd(path, &buffer);
-        if (r < 0)
-                return r;
-
-        if (_root) {
-                r = path_make_absolute_cwd(_root, &root);
+        if (original_root) {
+                r = path_make_absolute_cwd(original_root, &root);
                 if (r < 0)
                         return r;
+
+                if (flags & CHASE_PREFIX_ROOT)
+                        path = prefix_roota(root, path);
         }
 
+        r = path_make_absolute_cwd(path, &buffer);
+        if (r < 0)
+                return r;
+
         fd = open("/", O_CLOEXEC|O_NOFOLLOW|O_PATH);
         if (fd < 0)
                 return -errno;
@@ -797,13 +801,3 @@ int chase_symlinks(const char *path, const char *_root, char **ret) {
         return 0;
 }
 #endif // 0
-
-int chase_symlinks_prefix(const char *path, const char *root, char **ret) {
-        const char *t;
-
-        /* Same as chase_symlinks(), but prefixes 'path' by 'root' first. */
-
-        t = prefix_roota(root, path);
-
-        return chase_symlinks(t, root, ret);
-}
index d58b14801ba23c5f8520d2287536724167f0ea90..b5883b6c5cc630db8742546d222072405e17a67f 100644 (file)
@@ -91,5 +91,8 @@ union inotify_event_buffer {
 int inotify_add_watch_fd(int fd, int what, uint32_t mask);
 
 #endif // 0
-int chase_symlinks(const char *path_with_prefix, const char *root, char **ret);
-int chase_symlinks_prefix(const char *path_without_prefix, const char *root, char **ret);
+enum {
+        CHASE_PREFIX_ROOT = 1,   /* If set, the specified path will be prefixed by the specified root before beginning the iteration */
+};
+
+int chase_symlinks(const char *path_with_prefix, const char *root, unsigned flags, char **ret);
index 61190e40ac15f51a70f8d6fa0b45af28f9492052..d757abad90c3e4c73361ae8928aa06b34c6a464b 100644 (file)
@@ -691,35 +691,3 @@ int umount_verbose(const char *what) {
         return 0;
 }
 #endif // 0
-
-const char *mount_propagation_flags_to_string(unsigned long flags) {
-
-        switch (flags & (MS_SHARED|MS_SLAVE|MS_PRIVATE)) {
-
-        case MS_SHARED:
-                return "shared";
-
-        case MS_SLAVE:
-                return "slave";
-
-        case MS_PRIVATE:
-                return "private";
-        }
-
-        return NULL;
-}
-
-unsigned long mount_propagation_flags_from_string(const char *name) {
-
-        if (isempty(name))
-                return 0;
-
-        if (streq(name, "shared"))
-                return MS_SHARED;
-        if (streq(name, "slave"))
-                return MS_SLAVE;
-        if (streq(name, "private"))
-                return MS_PRIVATE;
-
-        return 0;
-}
index 9dd07333889fdc588811248b4bd8b26069f31cbe..84f327d7d050fbd4a6c1e98d21a6fb38316533a8 100644 (file)
@@ -254,7 +254,7 @@ char **path_strv_resolve(char **l, const char *root) {
                 } else
                         t = *s;
 
-                r = chase_symlinks(t, root, &u);
+                r = chase_symlinks(t, root, 0, &u);
                 if (r == -ENOENT) {
                         if (root) {
                                 u = orig;