# -*- coding: utf-8 -*-
# using log file not guarantee fully erased files from system
import os
import sys
import random
import argparse
def parse_args():
parser = argparse.ArgumentParser(description="XYardelete")
parser.add_argument("paths", nargs='+', help="path/file")
parser.add_argument("-r", "--range", type=str, default="3-8", help="amount of passes")
parser.add_argument("-l", "--logfile", type=str, default="deletion_log.txt", help="logfile")
return parser.parse_args()
def get_random_passes(range_str):
min_passes, max_passes = map(int, range_str.split('-'))
return random.randint(min_passes, max_passes)
def log(message, logfile):
print(message)
with open(logfile, "a") as log_file:
log_file.write(message + "\n")
def secure_delete_file(file_path, passes_range, logfile):
passes = get_random_passes(passes_range)
chunk_size = 1024 * 1024 # 1MB chunks // fixed size trouble v1
try:
with open(file_path, "r+b") as f:
length = os.path.getsize(file_path)
for pass_num in range(1, passes + 1):
f.seek(0)
for _ in range(0, length, chunk_size):
write_size = min(chunk_size, length - f.tell())
f.write(random.randbytes(write_size))
log(f"Pass {pass_num}/{passes} rewrite for {file_path}", logfile)
os.remove(file_path)
log(f"Deleted: {file_path}", logfile)
except Exception as e:
log(f"Error {file_path}: {e}", logfile)
def secure_delete(path, passes_range, logfile):
if os.path.isdir(path):
for root, dirs, files in os.walk(path, topdown=False):
for name in files:
file_path = os.path.join(root, name)
secure_delete_file(file_path, passes_range, logfile)
for name in dirs:
os.rmdir(os.path.join(root, name))
log(f"Dir deleted: {os.path.join(root, name)}", logfile)
os.rmdir(path)
log(f"Dir deleted: {path}", logfile)
elif os.path.isfile(path):
secure_delete_file(path, passes_range, logfile)
else:
log(f"Error: path not exists: {path}", logfile)
if __name__ == "__main__":
args = parse_args()
for path in args.paths:
secure_delete(path, args.range, args.logfile)