#!/usr/bin/perl

use strict;
use warnings;
use IO::File;

$|=1;

my $file;

sub randomString(){
	my $fetch=(int(rand(512))+512)*16384;
	my $data='';
	my $packet;
	my $fh=new IO::File('/dev/urandom','r')
		|| die("Unable to open /dev/urandom: $!\n");
	binmode($fh);
	while(length($data) < $fetch){
		printf("\rGenerating %d bytes urandom string... %d%%",$fetch,(length($data)*100/$fetch));
		read($fh,$packet,8192);
		$data.=$packet;
	}
	$fh->close();
	printf("\rGenerating %d bytes urandom string... done\n",$fetch);
	return($data);
}

sub fillDisk($){
	my $string=shift;
	my $written=0;
	my $size=length($string);
	my $started=time;
	my $mbytes;
	$SIG{TERM}=$SIG{INT}=sub{
			print("\n");
			removeFile();
			exit(1);
		};
	my $fh=new IO::File($file,'w')
		|| die("Unable to open $file: $!\n");
	binmode($fh);
	while(print($fh $string)){
		$written+=$size;
		$mbytes=$written/1048576;
		printf("\rWriting growing file to disk... %d MB (%d MB/s)   ",$mbytes,($mbytes/((time-$started)||1)));
	}
	$fh->close();
	print("\n");
}

sub syncDisk(){
	print('Writing cached data to disk... ');
	system('/bin/sync');
	print("done\n");
}

sub removeFile(){
	print('Removing the growing file from disk... ');
	unlink($file);
	system('/bin/sync');
	print("done\n");
}

sub showUsage(){
print(<<__EOF);
This programm will generate a urandom string of 8 to 16 MBytes,
repeatedly write this into the given file until writing becomes impossible
and remove the file from disk.

The given file must NOT exist!

Usage: $0 <filename>

__EOF
	exit(1);
}

sub main(){
	$file=$ARGV[0];
	print("Randomize Free Space, (C)2006 Veit Wahlich <cru at zodia dot de>\n\n");
	unless(defined($file) && $file=~/^[^\-]/ && not(-e $file)){
		showUsage();
	}
	fillDisk(randomString());
	syncDisk();
	removeFile();
	exit(0);
}

main();
1;