pub mod del {
use std::fs::{self, File};
use std::io::{self, Read, Write};
use rand::Rng;
use ring::digest;
use filetime::{self, FileTime, set_file_times};
use std::path::Path;
const NUM_HASH_PASSES: usize = 35; const BUFFER_SIZE: usize = 1024;
fn remove_magic_number(data: &mut Vec<u8>) {
let mut rng = rand::thread_rng();
let magic_number = 0xDEADBEEFu32;
for chunk in data.chunks_mut(4) {
if chunk.len() == 4 && u32::from_le_bytes([chunk[0], chunk[1], chunk[2], chunk[3]]) == magic_number {
let random_data: u32 = rng.gen();
let bytes = random_data.to_le_bytes();
chunk[0] = bytes[0];
chunk[1] = bytes[1];
chunk[2] = bytes[2];
chunk[3] = bytes[3];
}
}
}
pub fn secure_delete_file(file_path: &str) -> io::Result<()> {
let mut file = File::open(file_path)?;
let mut data = Vec::new();
file.read_to_end(&mut data)?;
remove_magic_number(&mut data);
let mut file = File::create(file_path)?;
for _ in 0..NUM_HASH_PASSES {
let mut hasher = digest::Context::new(&digest::SHA256);
hasher.update(&data);
let hash = hasher.finish();
file.write_all(hash.as_ref())?;
data = hash.as_ref().to_vec();
}
file.sync_all()?;
let metadata = fs::metadata(file_path)?;
let mut rng = rand::thread_rng();
let atime = FileTime::from_unix_time(rng.gen(), 0);
let mtime = FileTime::from_unix_time(rng.gen(), 0);
set_file_times(Path::new(file_path), atime, mtime)?;
let mut deleted_path = file_path.to_owned();
deleted_path.push_str(".deleted");
fs::rename(file_path, &deleted_path)?;
Ok(())
}
}