|
|
|
@ -11,6 +11,7 @@ use crate::common_items::ExcludedItems;
|
|
|
|
|
use crate::common_messages::Messages;
|
|
|
|
|
use crate::common_traits::*;
|
|
|
|
|
use crossbeam_channel::Receiver;
|
|
|
|
|
use rayon::prelude::*;
|
|
|
|
|
|
|
|
|
|
#[derive(Eq, PartialEq, Clone, Debug)]
|
|
|
|
|
pub enum DeleteMethod {
|
|
|
|
@ -54,6 +55,7 @@ pub struct ZeroedFiles {
|
|
|
|
|
delete_method: DeleteMethod,
|
|
|
|
|
stopped_search: bool,
|
|
|
|
|
minimal_file_size: u64,
|
|
|
|
|
files_to_check: Vec<FileEntry>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ZeroedFiles {
|
|
|
|
@ -69,6 +71,7 @@ impl ZeroedFiles {
|
|
|
|
|
delete_method: DeleteMethod::None,
|
|
|
|
|
stopped_search: false,
|
|
|
|
|
minimal_file_size: 1024,
|
|
|
|
|
files_to_check: Vec::with_capacity(1024),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -78,6 +81,10 @@ impl ZeroedFiles {
|
|
|
|
|
self.stopped_search = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if !self.check_for_zeroed_files(stop_receiver) {
|
|
|
|
|
self.stopped_search = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
self.delete_files();
|
|
|
|
|
self.debug_print();
|
|
|
|
|
}
|
|
|
|
@ -210,42 +217,87 @@ impl ZeroedFiles {
|
|
|
|
|
continue 'dir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let mut file_handler: File = match File::open(¤t_file_name) {
|
|
|
|
|
Ok(t) => t,
|
|
|
|
|
// Creating new file entry
|
|
|
|
|
let fe: FileEntry = FileEntry {
|
|
|
|
|
path: current_file_name.clone(),
|
|
|
|
|
size: metadata.len(),
|
|
|
|
|
modified_date: match metadata.modified() {
|
|
|
|
|
Ok(t) => match t.duration_since(UNIX_EPOCH) {
|
|
|
|
|
Ok(d) => d.as_secs(),
|
|
|
|
|
Err(_) => {
|
|
|
|
|
continue 'dir;
|
|
|
|
|
self.text_messages.warnings.push(format!("File {} seems to be modified before Unix Epoch.", current_file_name.display()));
|
|
|
|
|
0
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
Err(_) => {
|
|
|
|
|
self.text_messages.warnings.push(format!("Unable to get modification date from file {}", current_file_name.display()));
|
|
|
|
|
continue;
|
|
|
|
|
} // Permissions Denied
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let mut first_search: bool = true;
|
|
|
|
|
// Adding files to Vector
|
|
|
|
|
self.files_to_check.push(fe);
|
|
|
|
|
|
|
|
|
|
self.information.number_of_checked_files += 1;
|
|
|
|
|
} else {
|
|
|
|
|
// Probably this is symbolic links so we are free to ignore this
|
|
|
|
|
self.information.number_of_ignored_things += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Common::print_time(start_time, SystemTime::now(), "check_files".to_string());
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Check files for files which have 0
|
|
|
|
|
fn check_for_zeroed_files(&mut self, stop_receiver: Option<&Receiver<()>>) -> bool {
|
|
|
|
|
let start_time: SystemTime = SystemTime::now();
|
|
|
|
|
|
|
|
|
|
self.zeroed_files = self
|
|
|
|
|
.files_to_check
|
|
|
|
|
.par_iter()
|
|
|
|
|
.map(|file_entry| {
|
|
|
|
|
if stop_receiver.is_some() && stop_receiver.unwrap().try_recv().is_ok() {
|
|
|
|
|
// This will not break
|
|
|
|
|
return None;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let file_entry = file_entry.clone();
|
|
|
|
|
let mut n;
|
|
|
|
|
loop {
|
|
|
|
|
if first_search {
|
|
|
|
|
let mut file_handler: File = match File::open(&file_entry.path) {
|
|
|
|
|
Ok(t) => t,
|
|
|
|
|
Err(_) => {
|
|
|
|
|
return Some(None);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// First search
|
|
|
|
|
let mut buffer = [0u8; 64];
|
|
|
|
|
n = match file_handler.read(&mut buffer) {
|
|
|
|
|
Ok(t) => t,
|
|
|
|
|
Err(_) => {
|
|
|
|
|
continue 'dir;
|
|
|
|
|
return Some(None);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
for i in buffer[0..n].iter() {
|
|
|
|
|
if *i != 0 {
|
|
|
|
|
continue 'dir; // Not zeroed file
|
|
|
|
|
return Some(None);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
first_search = false;
|
|
|
|
|
} else {
|
|
|
|
|
// Second search
|
|
|
|
|
loop {
|
|
|
|
|
let mut buffer = [0u8; 1024 * 32];
|
|
|
|
|
n = match file_handler.read(&mut buffer) {
|
|
|
|
|
Ok(t) => t,
|
|
|
|
|
Err(_) => {
|
|
|
|
|
continue 'dir;
|
|
|
|
|
return Some(None);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
for i in buffer[0..n].iter() {
|
|
|
|
|
if *i != 0 {
|
|
|
|
|
continue 'dir; // Not zeroed file
|
|
|
|
|
}
|
|
|
|
|
return Some(None);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if n == 0 {
|
|
|
|
@ -253,38 +305,16 @@ impl ZeroedFiles {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Creating new file entry
|
|
|
|
|
let fe: FileEntry = FileEntry {
|
|
|
|
|
path: current_file_name.clone(),
|
|
|
|
|
size: metadata.len(),
|
|
|
|
|
modified_date: match metadata.modified() {
|
|
|
|
|
Ok(t) => match t.duration_since(UNIX_EPOCH) {
|
|
|
|
|
Ok(d) => d.as_secs(),
|
|
|
|
|
Err(_) => {
|
|
|
|
|
self.text_messages.warnings.push(format!("File {} seems to be modified before Unix Epoch.", current_file_name.display()));
|
|
|
|
|
0
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
Err(_) => {
|
|
|
|
|
self.text_messages.warnings.push(format!("Unable to get modification date from file {}", current_file_name.display()));
|
|
|
|
|
continue;
|
|
|
|
|
} // Permissions Denied
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
Some(Some(file_entry))
|
|
|
|
|
})
|
|
|
|
|
.while_some()
|
|
|
|
|
.filter(|file_entry| file_entry.is_some())
|
|
|
|
|
.map(|file_entry| file_entry.unwrap())
|
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
|
|
|
|
// Adding files to Vector
|
|
|
|
|
self.zeroed_files.push(fe);
|
|
|
|
|
|
|
|
|
|
self.information.number_of_checked_files += 1;
|
|
|
|
|
} else {
|
|
|
|
|
// Probably this is symbolic links so we are free to ignore this
|
|
|
|
|
self.information.number_of_ignored_things += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
self.information.number_of_zeroed_files = self.zeroed_files.len();
|
|
|
|
|
|
|
|
|
|
Common::print_time(start_time, SystemTime::now(), "check_files".to_string());
|
|
|
|
|
Common::print_time(start_time, SystemTime::now(), "search for zeroed_files".to_string());
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|