@@ -17,6 +17,7 @@ use std::path::{Path, PathBuf};
1717use uucore:: display:: Quotable ;
1818use uucore:: error:: { FromIo , UResult , USimpleError , UUsageError } ;
1919use uucore:: parse_size:: parse_size_u64;
20+ use uucore:: rand_read:: { ReadRng , WrappedRng } ;
2021use uucore:: shortcut_value_parser:: ShortcutValueParser ;
2122use uucore:: { format_usage, help_about, help_section, help_usage, show_error, show_if_err} ;
2223
@@ -34,6 +35,7 @@ pub mod options {
3435 pub const VERBOSE : & str = "verbose" ;
3536 pub const EXACT : & str = "exact" ;
3637 pub const ZERO : & str = "zero" ;
38+ pub const RANDOM_SOURCE : & str = "random-source" ;
3739
3840 pub mod remove {
3941 pub const UNLINK : & str = "unlink" ;
@@ -261,6 +263,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
261263 let exact = matches. get_flag ( options:: EXACT ) || size. is_some ( ) ;
262264 let zero = matches. get_flag ( options:: ZERO ) ;
263265 let verbose = matches. get_flag ( options:: VERBOSE ) ;
266+ let random_source = matches
267+ . get_one :: < String > ( options:: RANDOM_SOURCE )
268+ . map ( String :: from) ;
264269
265270 for path_str in matches. get_many :: < String > ( options:: FILE ) . unwrap ( ) {
266271 show_if_err ! ( wipe_file(
@@ -272,6 +277,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
272277 zero,
273278 verbose,
274279 force,
280+ & random_source
275281 ) ) ;
276282 }
277283 Ok ( ( ) )
@@ -357,6 +363,13 @@ pub fn uu_app() -> Command {
357363 . action ( ArgAction :: Append )
358364 . value_hint ( clap:: ValueHint :: FilePath ) ,
359365 )
366+ . arg (
367+ Arg :: new ( options:: RANDOM_SOURCE )
368+ . long ( options:: RANDOM_SOURCE )
369+ . value_name ( "FILE" )
370+ . help ( "get random bytes from FILE" )
371+ . value_hint ( clap:: ValueHint :: FilePath ) ,
372+ )
360373}
361374
362375fn get_size ( size_str_opt : Option < String > ) -> Option < u64 > {
@@ -392,6 +405,7 @@ fn wipe_file(
392405 zero : bool ,
393406 verbose : bool ,
394407 force : bool ,
408+ random_source : & Option < String > ,
395409) -> UResult < ( ) > {
396410 // Get these potential errors out of the way first
397411 let path = Path :: new ( path_str) ;
@@ -452,7 +466,17 @@ fn wipe_file(
452466 for pattern in PATTERNS . into_iter ( ) . take ( remainder) {
453467 pass_sequence. push ( PassType :: Pattern ( pattern) ) ;
454468 }
455- let mut rng = rand:: thread_rng ( ) ;
469+
470+ let mut rng = match random_source {
471+ Some ( r) => {
472+ let file = File :: open ( & r[ ..] ) . map_err_context ( || {
473+ format ! ( "failed to open random source {}" , r. quote( ) )
474+ } ) ?;
475+ WrappedRng :: RngFile ( ReadRng :: new ( file) )
476+ }
477+ None => WrappedRng :: RngDefault ( rand:: thread_rng ( ) ) ,
478+ } ;
479+
456480 pass_sequence. shuffle ( & mut rng) ; // randomize the order of application
457481
458482 let n_random = 3 + n_passes / 10 ; // Minimum 3 random passes; ratio of 10 after
@@ -501,6 +525,7 @@ fn wipe_file(
501525 do_remove ( path, path_str, verbose, remove_method)
502526 . map_err_context ( || format ! ( "{}: failed to remove file" , path. maybe_quote( ) ) ) ?;
503527 }
528+
504529 Ok ( ( ) )
505530}
506531
0 commit comments