coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Add wipename option to shred


From: Joseph D. Wagner
Subject: [PATCH] Add wipename option to shred
Date: Mon, 10 Jun 2013 23:20:34 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130514 Thunderbird/17.0.6

Currently, when --remove (-u) is specified, shred overwrites the file
name once for each character, so a file name of 0123456789 would be
overridden 10 times. While this may be the most secure, it is also the
most time consuming as each of the 10 renames has its own fsync. Also,
renaming may not be as effective on some journaled file systems.

This patch adds the option --wipename (-w) which accepts the options:
* perchar - overwrite file name once per character; same as current.
* once - overwrite file name once total.
* none - skip overwrite of file name entirely; just unlink.
If --remove is specified but not --wipename, perchar is assumed,
preserving current behavior. Specifying --wipename implies --remove.

In theory, this should provide improved performance for those who
choose it, especially when deleting many small files.  I am currently
testing performance on my system, but I wanted to get the ball rolling
by soliciting your comments and your receptiveness to accepting this
patch.

Thoughts?

Joseph D. Wagner

diff -r -u -- old/src/shred.c new/src/shred.c
--- old/src/shred.c    2013-01-30 16:46:24.000000000 -0800
+++ new/src/shred.c    2013-06-10 22:42:11.179688884 -0700
@@ -111,6 +111,7 @@
   off_t size;        /* -s flag: size of file */
   bool remove_file;    /* -u flag: remove file after shredding */
   bool verbose;        /* -v flag: Print progress */
+  size_t wipename;    /* -w flag: Number of name overwrites */
   bool exact;        /* -x flag: Do not round up file size */
   bool zero_fill;    /* -z flag: Add a final zero pass */
 };
@@ -131,6 +132,7 @@
   {"random-source", required_argument, NULL, RANDOM_SOURCE_OPTION},
   {"remove", no_argument, NULL, 'u'},
   {"verbose", no_argument, NULL, 'v'},
+  {"wipename", required_argument, NULL, 'w'},
   {"zero", no_argument, NULL, 'z'},
   {GETOPT_HELP_OPTION_DECL},
   {GETOPT_VERSION_OPTION_DECL},
@@ -161,6 +163,8 @@
       fputs (_("\
   -u, --remove   truncate and remove file after overwriting\n\
   -v, --verbose  show progress\n\
+  -w, --wipename=OPTION  overwrite name OPTION times\n\
+                   (perchar, once, none); implies --remove\n\
   -x, --exact    do not round file sizes up to the next full block;\n\
                    this is the default for non-regular files\n\
   -z, --zero     add a final overwrite with zeros to hide shredding\n\
@@ -956,6 +960,7 @@
   char *newname = xstrdup (oldname);
   char *base = last_component (newname);
   size_t len = base_len (base);
+  size_t wipes = flags->wipename;
   char *dir = dir_name (newname);
   char *qdir = xstrdup (quotearg_colon (dir));
   bool first = true;
@@ -966,7 +971,7 @@
   if (flags->verbose)
     error (0, 0, _("%s: removing"), qoldname);

-  while (len)
+  while (len && wipes)
     {
       memset (base, nameset[0], len);
       base[len] = 0;
@@ -1007,6 +1012,7 @@
         }
       while (incname (base, len));
       len--;
+      wipes--;
     }
   if (unlink (oldname) != 0)
     {
@@ -1107,8 +1113,9 @@

   flags.n_iterations = DEFAULT_PASSES;
   flags.size = -1;
+  flags.wipename = UCHAR_MAX + 1;

- while ((c = getopt_long (argc, argv, "fn:s:uvxz", long_opts, NULL)) != -1) + while ((c = getopt_long (argc, argv, "fn:s:uvw:xz", long_opts, NULL)) != -1)
     {
       switch (c)
         {
@@ -1135,6 +1142,18 @@
           random_source = optarg;
           break;

+        case 'w':
+          if (STREQ (optarg, "none"))
+            flags.wipename = 0;
+          else if (STREQ (optarg, "once"))
+            flags.wipename = 1;
+          else if (STREQ (optarg, "perchar"))
+            flags.wipename = UCHAR_MAX + 1;
+          else
+            {
+              error (EXIT_FAILURE, 0, _("%s: invalid wipename option"),
+                     quotearg_colon (optarg));
+            }
         case 'u':
           flags.remove_file = true;
           break;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]