Blame SOURCES/scrub-2.6.1-symlinks-to-block-device.patch

6c3643
From 499a491c21b5a18be79334282dfa11fd4f408c49 Mon Sep 17 00:00:00 2001
6c3643
From: Sergio Correia <scorreia@redhat.com>
6c3643
Date: Wed, 27 Jan 2021 09:42:15 -0300
6c3643
Subject: [PATCH] scrub should work for symlinks pointing to block devices
6c3643
6c3643
In [1] (add -L option to avoid scrubbing symlink target [Tim
6c3643
Boronczyk]), scrub introduced a -L (--no-link) option so that it would
6c3643
not scrub the target, if it was a link and this new option was set.
6c3643
6c3643
A side-effect of that change is that scrub stopped working for links
6c3643
pointing to a block device, whereas it would still work for links
6c3643
pointing to regular files -- it is not clear from the commit changelog
6c3643
and the added documentation for this new option that this was an
6c3643
intended change.
6c3643
6c3643
In this commit we fix this regression, and scrub works again for links
6c3643
pointing to block devices. -L/--no-link option also works for these
6c3643
links.
6c3643
6c3643
[1] https://github.com/chaos/scrub/commit/01915c442288b4b274261fa07e42e116fb9d6b60
6c3643
---
6c3643
 src/scrub.c | 13 ++++++++-----
6c3643
 src/util.c  | 13 +++++++++----
6c3643
 src/util.h  |  2 +-
6c3643
 3 files changed, 18 insertions(+), 10 deletions(-)
6c3643
6c3643
diff --git a/src/scrub.c b/src/scrub.c
6c3643
index 1dada28..178dfe7 100644
6c3643
--- a/src/scrub.c
6c3643
+++ b/src/scrub.c
6c3643
@@ -334,6 +334,10 @@ static int scrub_object(char *filename, const struct opt_struct *opt,
6c3643
                 fprintf(stderr, "%s: %s already scrubbed? (-f to force)\n",
6c3643
                         prog, filename);
6c3643
                 errcount++;
6c3643
+            } else if (is_symlink(filename) && opt->nofollow) {
6c3643
+                fprintf(stderr, "%s: skipping symlink %s because --no-link (-L) option was set\n",
6c3643
+                        prog, filename);
6c3643
+                errcount++;
6c3643
             } else if (!noexec) {
6c3643
                 if (dryrun) {
6c3643
                     printf("%s: (dryrun) scrub special file %s\n",
6c3643
@@ -343,8 +347,8 @@ static int scrub_object(char *filename, const struct opt_struct *opt,
6c3643
                 }
6c3643
             }
6c3643
             break;
6c3643
-        case FILE_LINK:
6c3643
-            if (opt->nofollow) {
6c3643
+        case FILE_REGULAR:
6c3643
+            if (is_symlink(filename) && opt->nofollow) {
6c3643
                 if (opt->remove && !noexec) {
6c3643
                     if (dryrun) {
6c3643
                         printf("%s: (dryrun) unlink %s\n", prog, filename);
6c3643
@@ -359,8 +363,7 @@ static int scrub_object(char *filename, const struct opt_struct *opt,
6c3643
                 }
6c3643
                 break;
6c3643
             }
6c3643
-            /* FALL THRU */
6c3643
-        case FILE_REGULAR:
6c3643
+
6c3643
             if (access(filename, R_OK|W_OK) < 0) {
6c3643
                 fprintf(stderr, "%s: no rw access to %s\n", prog, filename);
6c3643
                 errcount++;
6c3643
@@ -670,7 +673,7 @@ scrub_file(char *path, const struct opt_struct *opt)
6c3643
     filetype_t ftype = filetype(path);
6c3643
     off_t size = opt->devsize;
6c3643
 
6c3643
-    assert(ftype == FILE_REGULAR || ftype == FILE_LINK);
6c3643
+    assert(ftype == FILE_REGULAR);
6c3643
 
6c3643
     if (stat(path, &sb) < 0) {
6c3643
         fprintf(stderr, "%s: stat %s: %s\n", prog, path, strerror(errno));
6c3643
diff --git a/src/util.c b/src/util.c
6c3643
index 96dd59b..fb85368 100644
6c3643
--- a/src/util.c
6c3643
+++ b/src/util.c
6c3643
@@ -71,6 +71,15 @@ write_all(int fd, const unsigned char *buf, int count)
6c3643
     return n;
6c3643
 }
6c3643
 
6c3643
+/* Indicates whether the file represented by 'path' is a symlink.
6c3643
+ */
6c3643
+int
6c3643
+is_symlink(char *path)
6c3643
+{
6c3643
+    struct stat sb;
6c3643
+    return lstat(path, &sb) == 0 && S_ISLNK(sb.st_mode);
6c3643
+}
6c3643
+
6c3643
 /* Return the type of file represented by 'path'.
6c3643
  */
6c3643
 filetype_t
6c3643
@@ -80,10 +89,6 @@ filetype(char *path)
6c3643
 
6c3643
     filetype_t res = FILE_NOEXIST;
6c3643
 
6c3643
-    if (lstat(path, &sb) == 0 && S_ISLNK(sb.st_mode)) {
6c3643
-        return FILE_LINK;
6c3643
-    }
6c3643
-
6c3643
     if (stat(path, &sb) == 0) {
6c3643
         if (S_ISREG(sb.st_mode))
6c3643
             res = FILE_REGULAR;
6c3643
diff --git a/src/util.h b/src/util.h
6c3643
index 513ae48..04246df 100644
6c3643
--- a/src/util.h
6c3643
+++ b/src/util.h
6c3643
@@ -13,7 +13,6 @@ typedef enum {
6c3643
     FILE_REGULAR,
6c3643
     FILE_CHAR,
6c3643
     FILE_BLOCK,
6c3643
-    FILE_LINK,
6c3643
     FILE_OTHER,
6c3643
 } filetype_t;
6c3643
 
6c3643
@@ -21,6 +20,7 @@ typedef enum { UP, DOWN } round_t;
6c3643
 
6c3643
 int         read_all(int fd, unsigned char *buf, int count);
6c3643
 int         write_all(int fd, const unsigned char *buf, int count);
6c3643
+int         is_symlink(char *path);
6c3643
 filetype_t  filetype(char *path);
6c3643
 off_t       blkalign(off_t offset, int blocksize, round_t rtype);
6c3643
 void *      alloc_buffer(int bufsize);