#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Sovrascrittura spazio libero (adatto a cellulari/Termux) Crea un file temporaneo pieno di dati casuali. Per fermarlo: - Termux: Volume giù + C - Qualsiasi terminale: creare un file "stop.wipe" nella dir di esecuzione """ import os import sys import time import signal # Configurazione CHUNK_SIZE = 1024 * 1024 # 1 MB per volta PROGRESS_INTERVAL = 50 # aggiorna ogni 50 chunk (50 MB) TEMP_FILENAME = ".wipe_free_space.tmp" STOP_FILE = "stop.wipe" # Se esiste, arresta il riempimento def get_free_space(path): stat = os.statvfs(path) return stat.f_bsize * stat.f_bavail def format_bytes(n): for unit in ("B", "KB", "MB", "GB", "TB"): if n < 1024: return f"{n:.1f} {unit}" n /= 1024 return f"{n:.1f} PB" def format_time(seconds): m, s = divmod(int(seconds), 60) h, m = divmod(m, 60) if h: return f"{h:02d}:{m:02d}:{s:02d}" return f"{m:02d}:{s:02d}" def wipe_free_space(target_dir): file_path = os.path.join(target_dir, TEMP_FILENAME) stop_path = os.path.join(target_dir, STOP_FILE) if not os.path.isdir(target_dir): print(f"[ERRORE] Directory '{target_dir}' inesistente.") sys.exit(1) if not os.access(target_dir, os.W_OK): print(f"[ERRORE] Permessi di scrittura mancanti su '{target_dir}'.") sys.exit(1) free_start = get_free_space(target_dir) if free_start == 0: print("Spazio libero già esaurito.") return print(f"Directory: {target_dir}") print(f"Spazio libero iniziale: {format_bytes(free_start)}") print(f"File temporaneo: {file_path}") print("Per fermare: crea un file 'stop.wipe' in questa directory") print(" oppure (Termux) Volume giù + C\n") # Rimuovi eventuale file di stop residuo if os.path.exists(stop_path): os.remove(stop_path) start_time = time.monotonic() total_written = 0 last_update = 0 try: with open(file_path, "wb") as f: while True: # Controllo file di stop ogni chunk if os.path.exists(stop_path): print("\n[STOP] File stop.wipe rilevato. Interruzione pulita.") break data = os.urandom(CHUNK_SIZE) try: f.write(data) f.flush() except OSError as e: if e.errno == 28: # Spazio esaurito break raise total_written += CHUNK_SIZE last_update += 1 if last_update >= PROGRESS_INTERVAL: last_update = 0 elapsed = time.monotonic() - start_time speed = total_written / elapsed if elapsed > 0 else 0 remaining = free_start - total_written eta = remaining / speed if speed > 0 else 0 pct = min(100.0, (total_written / free_start) * 100) bar_len = 30 filled = int(bar_len * total_written / free_start) bar = '█' * filled + '░' * (bar_len - filled) print(f"\r[{bar}] {pct:5.1f}% " f"Scritto: {format_bytes(total_written)} " f"Velocità: {format_bytes(speed)}/s " f"ETA: {format_time(eta)} ", end="", flush=True) elapsed = time.monotonic() - start_time if total_written > 0: print(f"\nOperazione completata dopo {format_time(elapsed)}. " f"Totale scritto: {format_bytes(total_written)}") else: print("\nNessun dato scritto.") except KeyboardInterrupt: print("\n\n[Ctrl+C] Interruzione manuale. Pulizia...") except Exception as e: print(f"\n[ERRORE] {e}") finally: if os.path.exists(file_path): try: os.remove(file_path) print(f"File temporaneo '{file_path}' rimosso.") except Exception as e: print(f"[ATTENZIONE] Rimozione fallita: {e}") # Rimuovi anche il file di stop se esiste (pulizia) if os.path.exists(stop_path): os.remove(stop_path) def main(): # Per rendere il segnale SIGINT gestibile anche fuori dal loop signal.signal(signal.SIGINT, lambda sig, frame: sys.exit(0)) if len(sys.argv) > 1: target = sys.argv[1] else: target = os.getcwd() # Se ambiente Android (Termux) e non è stata passata una dir, default a /sdcard if "ANDROID_DATA" in os.environ and target == os.getcwd(): target = "/sdcard" print(f"Ambiente Android, uso '{target}' come predefinito.") wipe_free_space(target) if __name__ == "__main__": main()