GNU bug report logs - #75531
[PATCH 1/1] Added new recursive feature to the shred command

Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.

Package: coreutils; Reported by: TheJostler <josj@HIDDEN>; Keywords: notabug patch; merged with #75532; Done: Pádraig Brady <P@HIDDEN>; Maintainer for coreutils is bug-coreutils@HIDDEN.
bug closed, send any further explanations to 75532 <at> debbugs.gnu.org and TheJostler <josj@HIDDEN> Request was from Pádraig Brady <P@HIDDEN> to control <at> debbugs.gnu.org. Full text available.
Added tag(s) notabug. Request was from Pádraig Brady <P@HIDDEN> to control <at> debbugs.gnu.org. Full text available.
Merged 75531 75532. Request was from Paul Eggert <eggert@HIDDEN> to control <at> debbugs.gnu.org. Full text available.

Message received at submit <at> debbugs.gnu.org:


Received: (at submit) by debbugs.gnu.org; 13 Jan 2025 06:03:15 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Mon Jan 13 01:03:15 2025
Received: from localhost ([127.0.0.1]:49875 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1tXDXe-0000CD-4j
	for submit <at> debbugs.gnu.org; Mon, 13 Jan 2025 01:03:15 -0500
Received: from lists.gnu.org ([2001:470:142::17]:45792)
 by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.84_2) (envelope-from <josj@HIDDEN>) id 1tX32p-0008Rw-2V
 for submit <at> debbugs.gnu.org; Sun, 12 Jan 2025 13:50:43 -0500
Received: from eggs.gnu.org ([2001:470:142:3::10])
 by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <josj@HIDDEN>) id 1tX32g-0001w8-Rd
 for bug-coreutils@HIDDEN; Sun, 12 Jan 2025 13:50:35 -0500
Received: from fly.ash.relay.mailchannels.net ([23.83.222.61])
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <josj@HIDDEN>) id 1tX32c-0000Hg-U0
 for bug-coreutils@HIDDEN; Sun, 12 Jan 2025 13:50:32 -0500
X-Sender-Id: hostingeremail|x-authuser|josj@HIDDEN
Received: from relay.mailchannels.net (localhost [127.0.0.1])
 by relay.mailchannels.net (Postfix) with ESMTP id 71C1D23DC2
 for <bug-coreutils@HIDDEN>; Sun, 12 Jan 2025 18:50:27 +0000 (UTC)
Received: from nl-srv-smtpout3.hostinger.io
 (trex-3.trex.outbound.svc.cluster.local [100.109.47.111])
 (Authenticated sender: hostingeremail)
 by relay.mailchannels.net (Postfix) with ESMTPA id C56A423CF9
 for <bug-coreutils@HIDDEN>; Sun, 12 Jan 2025 18:50:26 +0000 (UTC)
ARC-Seal: i=1; s=arc-2022; d=mailchannels.net; t=1736707827; a=rsa-sha256;
 cv=none;
 b=pgsZY8/I8H1CF00b46G94Yez1eruEHjbqAqhpaDs9FuspM++XceqHVVP8MTqDACKMZWH0/
 hHz8KnV9uZRrnM33uq/O+hNosozly+BLqYtrP/MjG4/Catn4nFNZ1OyL0WP2hITuxzpDRa
 JsGEvQzbdXrBQfopyXPFesY8OwArMFmDaT144NVjhoh4HjO++9d7kqEkLbQXc/CKSy2iYG
 s2F3lj7qPpDBHY4DcSYlutj96R8tJ2Hbk+WINlfnySUcURyeHI720CK5OOJextauKj0/C+
 JA0U8gvNCmO7lDplgAEUgPZfmDPIT2DvxZO00FusMJcHvHpjxeXxgFD27VQicQ==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed;
 d=mailchannels.net; s=arc-2022; t=1736707827;
 h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
 to:to:cc:cc:mime-version:mime-version:
 content-transfer-encoding:content-transfer-encoding:
 in-reply-to:in-reply-to:references:references:dkim-signature;
 bh=apI8+KdjaYwpn1aFgaY0h65E1oEQbDhcSdS+WriBHf0=;
 b=AuJEsjMf7uYOIIw+Rp0DpfCerMenMtkYiP8Zg2eA2l35bWtQ0biL+/9qzipGh7WSlVTOOD
 4KPz2/VWMAiIApmNqjN4kRuPXXWLaxO8ccHRnWP3DiiepFeZauwD/rGN7X2BbjojviCEZ8
 XQboe0mLH68UUjmiiaWwAQ10T1MY9vnCkvJhVbGRcMnLZ+ZrreybnvTgNseHdDIGDEUigS
 AJZbhyFUfReTjnoyET2hcnUnb+9tDM17ajs+KXeL8Lke7NcE78AWkLjgpqJIFlHF3joB6K
 8IIfNb2s4JuS50L18CoU/n7Gx+mdbnggsclkta0/yD4ZqsaRwdBjH15g5tmjMg==
ARC-Authentication-Results: i=1; rspamd-b5645c5d4-mkwsw;
 auth=pass smtp.auth=hostingeremail smtp.mailfrom=josj@HIDDEN
X-Sender-Id: hostingeremail|x-authuser|josj@HIDDEN
X-MC-Relay: Neutral
X-MailChannels-SenderId: hostingeremail|x-authuser|josj@HIDDEN
X-MailChannels-Auth-Id: hostingeremail
X-Towering-Trail: 6f3cceac5bad0ce9_1736707827316_256015485
X-MC-Loop-Signature: 1736707827316:2351129872
X-MC-Ingress-Time: 1736707827316
Received: from nl-srv-smtpout3.hostinger.io (nl-srv-smtpout3.hostinger.io
 [145.14.159.43]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384)
 by 100.109.47.111 (trex/7.0.2); Sun, 12 Jan 2025 18:50:27 +0000
From: TheJostler <josj@HIDDEN>
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tegosec.com;
 s=hostingermail-a; t=1736707824;
 h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
 to:to:cc:cc:mime-version:mime-version:
 content-transfer-encoding:content-transfer-encoding:
 in-reply-to:in-reply-to:references:references;
 bh=apI8+KdjaYwpn1aFgaY0h65E1oEQbDhcSdS+WriBHf0=;
 b=aEJw/3ZXjfTJxKcSYSf3U34QJq+qySDk9mGKEHW6TNUDYyQOt6D8AR4ZCefhlucjfOK0JD
 j6hdwFCyf7CLyrKKB0sWzECh1RuMifZUG659hbh1MCIycl28zetmd+kSzEUq2iJt6k5pAD
 iuZvzSvSrHOuvWh906slHBYeS6B8aSAgWmK7prJueLx2ZxsOFFtopRSFYHjbhLCaH0UTSU
 CBYBL+s2bIgrY4c7Mwbx03jSKmEYwEL6Srw/8WFGuYBgAljHMXA3phgljIkGVOwqDpVvN+
 8mQLmO3LPVk8DfvAQToxCSEk8/HEwp4GCewiDUE/3dnmh/utXuqy1IH/fy5KyQ==
To: bug-coreutils@HIDDEN
Subject: [PATCH 1/1] Added new recursive feature to the shred command
Message-Id: <20250112185020.124684-2-josj@HIDDEN>
X-Mailer: git-send-email 2.39.5
In-Reply-To: <20250112185020.124684-1-josj@HIDDEN>
References: <20250112185020.124684-1-josj@HIDDEN>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Date: Sun, 12 Jan 2025 18:50:24 +0000 (UTC)
X-CM-Analysis: v=2.4 cv=XvmoOkF9 c=1 sm=1 tr=0 ts=67840ef0
 a=LywaJTgNNuxJhQZtKkHN1Q==:117 a=LywaJTgNNuxJhQZtKkHN1Q==:17 a=bAK8nNZbAAAA:8
 a=IlWtQLDfXSg6abpHIbEA:9 a=5gdiso8aKJOKwWEKjupo:22
X-CM-Envelope: MS4xfBFzHYbHgO6SevSb0T591nc1dHxcdQBbxJVWqo83rMD0GJICxjQcJ/AHc1DiubBLX7UstrzeAcvlDEjEpMNAE0q9wHBu/Syh7mnfL6AhvTiHm4jh9mev
 FM43bLDfb/a0hoSrZ6osp3OeLPTgGsui1+4/6pzs8OgOrCau+BR3vSyRlMMpm4llsm4VdA/D5A4smrIFs7n9TVvqXjVOZLVdo50qfN0710qeU1kM34lXiA4/
X-AuthUser: josj@HIDDEN
Received-SPF: pass client-ip=23.83.222.61; envelope-from=josj@HIDDEN;
 helo=fly.ash.relay.mailchannels.net
X-Spam_score_int: -20
X-Spam_score: -2.1
X-Spam_bar: --
X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,
 DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,
 RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01,
 RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001,
 SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no
X-Spam_action: no action
X-Spam-Score: 1.0 (+)
X-Debbugs-Envelope-To: submit
X-Mailman-Approved-At: Mon, 13 Jan 2025 01:03:13 -0500
Cc: Josjuar Lister <josj@HIDDEN>
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -0.0 (/)

From: Josjuar Lister <josj@HIDDEN>

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





Acknowledgement sent to TheJostler <josj@HIDDEN>:
New bug report received and forwarded. Copy sent to bug-coreutils@HIDDEN. Full text available.
Report forwarded to bug-coreutils@HIDDEN:
bug#75531; Package coreutils. Full text available.
Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.
Last modified: Mon, 13 Jan 2025 11:00:02 UTC

GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997 nCipher Corporation Ltd, 1994-97 Ian Jackson.