--- old/src/shred.c 2016-12-16 14:36:58.819399157 +0100 +++ new/src/shred.c 2016-12-16 14:35:27.590639035 +0100 @@ -129,6 +129,7 @@ struct Options { bool force; /* -f flag: chmod files if necessary */ + bool shred_hard_links; /* -h flag: also shred file if nlink > 1 */ size_t n_iterations; /* -n flag: Number of iterations */ off_t size; /* -s flag: size of file */ enum remove_method remove_file; /* -u flag: remove file after shredding */ @@ -148,6 +149,7 @@ { {"exact", no_argument, NULL, 'x'}, {"force", no_argument, NULL, 'f'}, + {"shred-hard-links", no_argument, NULL, 'h'}, {"iterations", required_argument, NULL, 'n'}, {"size", required_argument, NULL, 's'}, {"random-source", required_argument, NULL, RANDOM_SOURCE_OPTION}, @@ -180,6 +182,7 @@ printf (_("\ -f, --force change permissions to allow writing if necessary\n\ + -h, --shred-hard-links also shred hard linked files\n\ -n, --iterations=N overwrite N times instead of the default (%d)\n\ --random-source=FILE get random bytes from FILE\n\ -s, --size=N shred this many bytes (suffixes like K, M, G accepted)\n\ @@ -891,6 +894,11 @@ error (0, 0, _("%s: file has negative size"), qname); return false; } + else if (st.st_nlink > 1 && ! flags->shred_hard_links) + { + error (0, 0, _("%s: file has %d > 1 hard links, use -h to shred anyway"), qname, st.st_nlink); + return false; + } /* Allocate pass array */ passarray = xnmalloc (flags->n_iterations, sizeof *passarray); @@ -1218,7 +1226,7 @@ main (int argc, char **argv) { bool ok = true; - struct Options flags = { 0, }; + struct Options flags = { 0, 0, }; char **file; int n_files; int c; @@ -1236,7 +1244,7 @@ flags.n_iterations = DEFAULT_PASSES; flags.size = -1; - while ((c = getopt_long (argc, argv, "fn:s:uvxz", long_opts, NULL)) != -1) + while ((c = getopt_long (argc, argv, "fhn:s:uvxz", long_opts, NULL)) != -1) { switch (c) { @@ -1244,6 +1252,10 @@ flags.force = true; break; + case 'h': + flags.shred_hard_links = true; + break; + case 'n': flags.n_iterations = xdectoumax (optarg, 0, MIN (ULONG_MAX,