[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: Shred recursive
From: |
Patterson, Shaun M Mr CTR USA AMC |
Subject: |
RE: Shred recursive |
Date: |
Mon, 29 Jun 2009 12:47:12 -0500 |
Well if anyone is interested the patch is below.
This is my first GNU submission...I tried to follow the GNU coding rules as
best as possible. I'm open to criticism.
--
Shaun
--- shred.c.orig 2009-06-29 13:36:11.485435000 -0400
+++ shred.c 2009-06-29 13:40:59.278678000 -0400
@@ -22,7 +22,6 @@
- use consistent non-capitalization in error messages
- add standard GNU copyleft comment
- - Add -r/-R/--recursive
- Add -i/--interactive
- Reserve -d
- Add -L
@@ -98,8 +97,14 @@
#include "fcntl--.h"
#include "human.h"
#include "quotearg.h" /* For quotearg_colon */
+#include "quote.h"
#include "randint.h"
#include "randread.h"
+#include "savedir.h"
+#include "filenamecat.h"
+
+
+
/* Default number of times to overwrite. */
enum { DEFAULT_PASSES = 3 };
@@ -118,6 +123,7 @@
{
bool force; /* -f flag: chmod files if necessary */
size_t n_iterations; /* -n flag: Number of iterations */
+ bool recursive; /* -R flag: Recursively shred directories */
off_t size; /* -s flag: size of file */
bool remove_file; /* -u flag: remove file after shredding */
bool verbose; /* -v flag: Print progress */
@@ -137,6 +143,7 @@
{"exact", no_argument, NULL, 'x'},
{"force", no_argument, NULL, 'f'},
{"iterations", required_argument, NULL, 'n'},
+ {"recursive", no_argument, NULL, 'R'},
{"size", required_argument, NULL, 's'},
{"random-source", required_argument, NULL, RANDOM_SOURCE_OPTION},
{"remove", no_argument, NULL, 'u'},
@@ -147,6 +154,24 @@
{NULL, 0, NULL, 0}
};
+
+/* For removing directories */
+extern int
+rmdir (char const *dir);
+
+static bool
+do_shred (char *cwd, const char *file_to_shred,
+ struct randint_source *randint_source, struct Options const
*flags);
+
+static bool
+shred_internal (char *cwd, const char *file_to_shred,
+ struct randint_source *randint_source, struct
Options const *flags);
+
+static bool
+wipefile (char *name, char const *qname,
+ struct randint_source *s, struct Options const *flags);
+
+
void
usage (int status)
{
@@ -168,6 +193,7 @@
-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\
+ -r, -R, --recursive shred directories recursively\n\
-s, --size=N shred this many bytes (suffixes like K, M, G accepted)\n\
"), DEFAULT_PASSES);
fputs (_("\
@@ -1017,6 +1043,7 @@
while (incname (base, len));
len--;
}
+
if (unlink (oldname) != 0)
{
error (0, errno, _("%s: failed to remove"), qoldname);
@@ -1024,6 +1051,7 @@
}
else if (flags->verbose)
error (0, 0, _("%s: removed"), qoldname);
+
if (0 <= dir_fd)
{
if (dosync (dir_fd, qdir) != 0)
@@ -1040,6 +1068,122 @@
return ok;
}
+
+/*
+ * Workhorse of the shred operation.
+ *
+ * Recursively shreds down directories if the recursive flag was passed
+ */
+static bool
+shred_internal (char *full_path_name, const char *file_to_shred,
+ struct randint_source *randint_source, struct
Options const *flags)
+{
+ struct stat st;
+ bool ok = false;
+
+ if (lstat (full_path_name, &st) < 0)
+ {
+ error (0, 0, _("failed to get attributes of %s"), quote
(full_path_name));
+ return false;
+ }
+
+ /* If name is a directory, list all the files and recursively
+ * shred on them */
+ if (S_ISDIR (st.st_mode))
+ {
+ /* Shredding directory */
+
+ if (flags->recursive)
+ {
+ /* Recursive flag set, grab all files/dirs in the directory
+ * and shred */
+
+ /* For clarity */
+ char *cwd = full_path_name;
+
+ /* Get a list of files in this directory */
+ char *files_in_directory = savedir (cwd);
+
+ char *file_name = files_in_directory;
+ while (*file_name != '\0')
+ {
+ ok &= do_shred (cwd, file_name, randint_source, flags);
+
+
+ file_name += strlen (file_name) + 1;
+ }
+
+
+ if (flags->remove_file)
+ {
+ if (rmdir (cwd) != 0)
+ {
+ error (0, errno, _("%s: failed to remove
directory"), cwd);
+ ok = false;
+ }
+ else if (flags->verbose)
+ error (0, 0, _("%s: removed"), cwd);
+ }
+
+ free (files_in_directory);
+
+ }
+ else
+ {
+ /* Do not shred directory */
+ error (0, 0, _("omitting directory %s"), quote
(full_path_name));
+ return false;
+ }
+
+
+ }
+ else
+ {
+ /* Shredding file */
+ char *qfull_path_name = xstrdup (quotearg_colon (full_path_name));
+
+ if (STREQ (file_to_shred, "-"))
+ {
+ ok &= wipefd (STDOUT_FILENO, qfull_path_name, randint_source,
flags);
+ }
+ else
+ {
+ ok &= wipefile (full_path_name, qfull_path_name,
randint_source, flags);
+ }
+
+ free (qfull_path_name);
+ }
+
+ return ok;
+}
+
+
+/*
+ * Shred file_to_shred
+ *
+ * If file_to_shred is a directory, the directory will be recursively shredded
+ * if the recursive option is set
+ *
+ */
+static bool
+do_shred (char *cwd, const char *file_to_shred,
+ struct randint_source *randint_source, struct Options const
*flags)
+{
+ /* current directory combined with the inputted file name */
+ char *full_path_name = file_name_concat (cwd, file_to_shred, NULL);
+
+ bool ok = false;
+
+ ok = shred_internal (full_path_name, file_to_shred, randint_source, flags);
+
+ free (full_path_name);
+
+ return ok;
+}
+
+
+
+
/*
* Finally, the function that actually takes a filename and grinds
* it into hamburger.
@@ -1114,10 +1258,17 @@
atexit (close_stdout);
+ /* Init flags to defaults */
+ flags.force = false;
flags.n_iterations = DEFAULT_PASSES;
+ flags.recursive = false;
flags.size = -1;
+ flags.remove_file = false;
+ flags.verbose = false;
+ flags.exact = false;
+ flags.zero_fill = false;
- while ((c = getopt_long (argc, argv, "fn:s:uvxz", long_opts, NULL)) != -1)
+ while ((c = getopt_long (argc, argv, "rRfn:s:uvxz", long_opts, NULL)) != -1)
{
switch (c)
{
@@ -1144,6 +1295,11 @@
random_source = optarg;
break;
+ case 'r':
+ case 'R':
+ flags.recursive = true;
+ break;
+
case 'u':
flags.remove_file = true;
break;
@@ -1198,17 +1354,9 @@
for (i = 0; i < n_files; i++)
{
- char *qname = xstrdup (quotearg_colon (file[i]));
- if (STREQ (file[i], "-"))
- {
- ok &= wipefd (STDOUT_FILENO, qname, randint_source, &flags);
- }
- else
- {
- /* Plain filename - Note that this overwrites *argv! */
- ok &= wipefile (file[i], qname, randint_source, &flags);
- }
- free (qname);
+ /* Note that this overwrites *argv! */
+ ok &= do_shred ("", file [i], randint_source, &flags);
+
}
exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
-----Original Message-----
From: Pádraig Brady [mailto:address@hidden
Sent: Monday, June 29, 2009 9:42 AM
To: Patterson, Shaun M Mr CTR USA AMC
Cc: address@hidden
Subject: Re: Shred recursive
Patterson, Shaun M Mr CTR USA AMC wrote:
> I have implemented a -r/-R/--recursive option in shred. Anyone
> interested or is piping shred with a find command enough?
Hmm, it's one of those marginal ones.
You wouldn't gain much really over using find.
Though in saying that, rm has this option, so it might be worthwhile to add to
allow one to: alias rm=shred Though I would never do that myself.
My vote is 60:40 against.
cheers,
Pádraig.