|
|
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);
|