]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
delta: extend skip logic to work on full directory paths (prefix+suffix)
authorFranck Bui <fbui@suse.com>
Mon, 4 Dec 2017 08:36:22 +0000 (09:36 +0100)
committerFranck Bui <fbui@suse.com>
Mon, 4 Dec 2017 11:43:21 +0000 (12:43 +0100)
Rather than only checking that a prefix path is a symlink to another prefix
path (this can happen with split-usr=true and /lib a symlink to /usr/lib),
extend the logic in should_skip_prefix() so that the check is done on the full
directory path (prefix + suffix).

This allows to catch such cases as well:

 # ls -ld /lib /lib/udev
 drwxr-xr-x 1 root root 86 Nov 22 13:14 /lib
 lrwxrwxrwx 1 root root 13 Sep  4 17:47 /lib/udev -> /usr/lib/udev

where prefix=/lib and suffix=udev/rules.d

src/delta/delta.c

index f626537438a261c9f85019397ea76943a15c5d6a..6d99d75d3df863fca220a8b21fdb7bb962d971b6 100644 (file)
@@ -392,19 +392,28 @@ static int enumerate_dir(
         return 0;
 }
 
-static int should_skip_prefix(const char* p) {
+static bool should_skip_path(const char *prefix, const char *suffix) {
 #if HAVE_SPLIT_USR
-        int r;
         _cleanup_free_ char *target = NULL;
+        const char *p;
+        char *dirname;
 
-        r = chase_symlinks(p, NULL, 0, &target);
-        if (r < 0)
-                return r;
+        dirname = strjoina(prefix, "/", suffix);
 
-        return !streq(p, target) && nulstr_contains(prefixes, target);
-#else
-        return 0;
+        if (chase_symlinks(dirname, NULL, 0, &target) < 0)
+                return false;
+
+        NULSTR_FOREACH(p, prefixes) {
+                if (path_startswith(dirname, p))
+                        continue;
+
+                if (path_equal(target, strjoina(p, "/", suffix))) {
+                        log_debug("%s redirects to %s, skipping.", dirname, target);
+                        return true;
+                }
+        }
 #endif
+        return false;
 }
 
 static int process_suffix(const char *suffix, const char *onlyprefix) {
@@ -434,14 +443,8 @@ static int process_suffix(const char *suffix, const char *onlyprefix) {
 
         NULSTR_FOREACH(p, prefixes) {
                 _cleanup_free_ char *t = NULL;
-                int skip;
 
-                skip = should_skip_prefix(p);
-                if (skip < 0) {
-                        r = skip;
-                        goto finish;
-                }
-                if (skip)
+                if (should_skip_path(p, suffix))
                         continue;
 
                 t = strjoin(p, "/", suffix);