GNU bug report logs -
#75531
[PATCH 1/1] Added new recursive feature to the shred command
Previous Next
Reported by: TheJostler <josj <at> tegosec.com>
Date: Mon, 13 Jan 2025 06:04:02 UTC
Severity: normal
Tags: notabug, patch
Merged with 75532
Done: Pádraig Brady <P <at> draigBrady.com>
Bug is archived. No further changes may be made.
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 75531 in the body.
You can then email your comments to 75531 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
bug-coreutils <at> gnu.org
:
bug#75531
; Package
coreutils
.
(Mon, 13 Jan 2025 06:04:02 GMT)
Full text and
rfc822 format available.
Acknowledgement sent
to
TheJostler <josj <at> tegosec.com>
:
New bug report received and forwarded. Copy sent to
bug-coreutils <at> gnu.org
.
(Mon, 13 Jan 2025 06:04:02 GMT)
Full text and
rfc822 format available.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
From: Josjuar Lister <josj <at> TegoSec.com>
---
src/shred.c | 111 +++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 97 insertions(+), 14 deletions(-)
diff --git a/src/shred.c b/src/shred.c
index 03a260243..c824fc495 100644
--- a/src/shred.c
+++ b/src/shred.c
@@ -128,6 +128,7 @@ static enum remove_method const remove_methods[] =
struct Options
{
+ bool recursive; /* -r flag: shred files and directories recursively */
bool force; /* -f flag: chmod files if necessary */
size_t n_iterations; /* -n flag: Number of iterations */
off_t size; /* -s flag: size of file */
@@ -179,6 +180,7 @@ If FILE is -, shred standard output.\n\
emit_mandatory_arg_note ();
printf (_("\
+ -r, --recursive shred files and directories recursively\n\
-f, --force change permissions to allow writing if necessary\n\
-n, --iterations=N overwrite N times instead of the default (%d)\n\
--random-source=FILE get random bytes from FILE\n\
@@ -1035,6 +1037,7 @@ incname (char *name, size_t len)
static bool
wipename (char *oldname, char const *qoldname, struct Options const *flags)
{
+ printf("wipename\n");
char *newname = xstrdup (oldname);
char *base = last_component (newname);
char *dir = dir_name (newname);
@@ -1079,13 +1082,28 @@ wipename (char *oldname, char const *qoldname, struct Options const *flags)
}
}
- if (unlink (oldname) != 0)
+ struct stat statbuf;
+ if (stat(oldname, &statbuf) == 0 && S_ISDIR(statbuf.st_mode))
{
- error (0, errno, _("%s: failed to remove"), qoldname);
- ok = false;
+ if (rmdir(oldname) != 0)
+ {
+ error(0, errno, _("%s: failed to remove directory"), qoldname);
+ ok = false;
+ }
+ else if (flags->verbose)
+ error(0, 0, _("%s: removed directory"), qoldname);
}
- else if (flags->verbose)
- error (0, 0, _("%s: removed"), qoldname);
+ else
+ {
+ if (unlink (oldname) != 0)
+ {
+ error (0, errno, _("%s: failed to remove"), qoldname);
+ ok = false;
+ }
+ else if (flags->verbose)
+ error (0, 0, _("%s: removed"), qoldname);
+ }
+
if (0 <= dir_fd)
{
if (dosync (dir_fd, qdir) != 0)
@@ -1138,11 +1156,73 @@ wipefile (char *name, char const *qname,
error (0, errno, _("%s: failed to close"), qname);
ok = false;
}
+ printf("remove_file: %u, Ok: %i\n", flags->remove_file, ok);
if (ok && flags->remove_file)
ok = wipename (name, qname, flags);
return ok;
}
+/* Wrapper for handling files simplifies the recursive function */
+static bool
+handle_file (char *name, struct randint_source *s, struct Options const *flags, bool ok)
+{
+ char *qname = xstrdup (quotef (name));
+ if (STREQ (name, "-"))
+ {
+ ok &= wipefd (STDOUT_FILENO, qname, s, flags);
+ }
+ else
+ {
+ /* Plain filename - Note that this overwrites *argv! */
+ ok &= wipefile (name, qname, s, flags);
+ }
+ free (qname);
+ return ok;
+}
+
+
+/* Directory wiping */
+static bool
+wipe_directory (char *name, struct randint_source *s, struct Options const *flags, bool ok)
+{
+ DIR *dir;
+ struct dirent *entry;
+ struct stat statbuf;
+ char path[PATH_MAX];
+
+ if (!(dir = opendir(name)))
+ {
+ error (0, errno, _("cannot open directory %s"), name);
+ return false;
+ }
+
+ while ((entry = readdir(dir)) != nullptr)
+ {
+ if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
+ continue;
+
+ snprintf(path, sizeof(path), "%s/%s", name, entry->d_name);
+ if (lstat(path, &statbuf) == -1)
+ {
+ error (0, errno, _("cannot stat %s"), path);
+ continue;
+ }
+
+ if (S_ISDIR(statbuf.st_mode))
+ {
+ if (!wipe_directory(path, s, flags, ok))
+ return false;
+ }
+ else
+ {
+ handle_file(path, s, flags, ok);
+ }
+ }
+ if (flags->remove_file)
+ ok &= wipename(name, name, flags);
+ closedir(dir);
+ return ok;
+}
/* Buffers for random data. */
static struct randint_source *randint_source;
@@ -1168,7 +1248,6 @@ main (int argc, char **argv)
int i;
char const *random_source = nullptr;
- initialize_main (&argc, &argv);
set_program_name (argv[0]);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
@@ -1179,10 +1258,14 @@ main (int argc, char **argv)
flags.n_iterations = DEFAULT_PASSES;
flags.size = -1;
- while ((c = getopt_long (argc, argv, "fn:s:uvxz", long_opts, nullptr)) != -1)
+ while ((c = getopt_long (argc, argv, "rfn:s:uvxz", long_opts, nullptr)) != -1)
{
switch (c)
{
+ case 'r':
+ flags.recursive = true;
+ flags.remove_file = remove_wipesync;
+ break;
case 'f':
flags.force = true;
break;
@@ -1249,21 +1332,21 @@ main (int argc, char **argv)
quotef (random_source ? random_source : "getrandom"));
atexit (clear_random_data);
+ struct stat statbuf;
for (i = 0; i < n_files; i++)
{
- char *qname = xstrdup (quotef (file[i]));
- if (STREQ (file[i], "-"))
+ if (stat(file[i], &statbuf) == 0 && S_ISDIR(statbuf.st_mode))
{
- ok &= wipefd (STDOUT_FILENO, qname, randint_source, &flags);
+ if (! ok){
+ continue;
+ }
+ ok &= wipe_directory (file[i], randint_source, &flags, ok);
}
else
{
- /* Plain filename - Note that this overwrites *argv! */
- ok &= wipefile (file[i], qname, randint_source, &flags);
+ ok &= handle_file (file[i], randint_source, &flags, ok);
}
- free (qname);
}
-
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
/*
--
2.39.5
Merged 75531 75532.
Request was from
Paul Eggert <eggert <at> cs.ucla.edu>
to
control <at> debbugs.gnu.org
.
(Mon, 13 Jan 2025 07:24:02 GMT)
Full text and
rfc822 format available.
Added tag(s) notabug.
Request was from
Pádraig Brady <P <at> draigBrady.com>
to
control <at> debbugs.gnu.org
.
(Mon, 13 Jan 2025 10:54:03 GMT)
Full text and
rfc822 format available.
bug closed, send any further explanations to
75532 <at> debbugs.gnu.org and TheJostler <josj <at> tegosec.com>
Request was from
Pádraig Brady <P <at> draigBrady.com>
to
control <at> debbugs.gnu.org
.
(Mon, 13 Jan 2025 10:54:03 GMT)
Full text and
rfc822 format available.
bug archived.
Request was from
Debbugs Internal Request <help-debbugs <at> gnu.org>
to
internal_control <at> debbugs.gnu.org
.
(Mon, 10 Feb 2025 12:24:10 GMT)
Full text and
rfc822 format available.
This bug report was last modified 131 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.