Using ntfsundelete (package NTFSPROGS) takes a lot of efford, so i created a little wizzard to do the trick. The script uses an object as wrapper for ntfsundelete, i think ill update it later with a gui as well.

Code for undelete:

#!/usr/bin/perl use 5.010; use strict; use warnings; use lib "/home/ivo/Scripts"; use UndeleteNTFS; my ($filename,$number,$directory,$device,$myuser); print "Welcome to UNDELETE, a Perl wrapper around NTFS UNDELETE !\n\n" +; print "Undelete only works on NTFS filesystems, also make sure NTFSPRO +GS is installed.\n"; print "This script must be run as root or with the sudo command as it +is required by NTFS UNDELETE.\n"; print "If your device is not yet unmounted, this Perl script will unmo +unt it for you if possible.\n\n\n"; print "Please enter device (e.g. /dev/sdd1) or type EXIT to exit\n"; chomp($device=<STDIN>); die "exiting" if ($device =~m/exit/i); print"\nJust a minute, this takes some time ...... (Perl is working 4U +).....\n"; my $undelete_obj = UndeleteNTFS->new(device=>$device); my @list=$undelete_obj->getundeletelist(); my $i=0; print "Number\t\tInode\tFlags\tAge\tDate\t\tSize\t\tFilename\n"; foreach (@list) { if (length($_->{size})<8) { #Print an extra tab after size if the size is a number wit +h less then 8 positions print "Number ".$i.":\t".$_->{inode}."\t".$_->{flags}."\t".$_- +>{age}."\t".$_->{date}."\t".$_->{size}."\t\t".$_->{filename}."\n"; } else { print "Number ".$i.":\t".$_->{inode}."\t".$_->{flags}."\t".$_- +>{age}."\t".$_->{date}."\t".$_->{size}."\t".$_->{filename}."\n"; } $i++; } print "Which number to undelete, type EXIT to exit ? \n"; chomp($number=<STDIN>); die "exiting" if ($number =~m/exit/i); print "Which filename for undelete, type EXIT to exit ? \n"; chomp($filename=<STDIN>); if ($filename eq "") { print "Assuming filename = undeleted.xxx\n\n\n"; } die "exiting" if ($filename =~m/exit/i); print "Which directory, type EXIT to exit ?\n"; chomp($directory=<stdin>); if ($directory eq "") { print "Assuming directory = HOME DIRECTORY\n\n\n"; } die "exiting" if ($directory =~m/exit/i); print "Which USER is owner of the undeleted file, type EXIT to exit ?\ +n"; chomp($myuser=<stdin>); if ($myuser eq "") { print "Assuming ROOT \n\n\n"; } die "exiting" if ($myuser =~m/exit/i); print"\nJust a minute, this takes time (depending on file size) ...... + (Perl is working 4U).....\n"; my @result=$undelete_obj->undeletefile( filename => $filename, number => $number, directory => $directory, user => $myuser ); print @result;

It uses a "use lib" directive, change that to your own directory. Code for the object:

use 5.010; use strict; use warnings; package UndeleteNTFS; sub new { #The constructor creates a hash containing: # - the device # - an array of hashes, each hash in the array equals to 1 line + of output from NTFSUNDELETE #A compiled regular expression (made with qr) is used to analyze e +ach line of output of NTFSUNDELETE and fill a hash #The hash is then pushed onto the output array of hashed my ($classname,%args)=@_; my ($inode, $flags, $age, $date, $size, $filename); die "Enter device" unless $args{device}; #Run the command and redirect STERR to STDOUT my @output = `ntfsundelete $args{device} 2>&1`; die "Script must be run in ROOT\n" if ($output[0]=~m/Toegang gewei +gerd/); if ($output[0]=~m/Access is denied/) #First line contains "Access denied", meaning device has been +mounted { #Trying to umount device system "sudo umount $args{device}"; #Retrying to get a list of files to be undeleted @output = `ntfsundelete $args{device} 2>&1`; } my $i=0; my $tmphash = { device => $args{device}, output => [] }; my $r_regex = qr/^(\d+)\s+([A-Z|.|!]+)\s+(\d+%)\s+([0-9|-]+)\s+(\d ++)\s+(.*)/; #my $r_regex = qr/^(\d+)\s+([A-Z|.|!]+)/; foreach (@output) { #Put each line of output in %tmphash2, then put %tmphash2 in +the $tmphash->{output} array of hashes my %tmphash2; $i++; next if ($i<3); #ignore first two lines of output if ($_ =~ $r_regex) { $tmphash2{inode}=$1; $tmphash2{flags}=$2; $tmphash2{age}=$3; $tmphash2{date}=$4; $tmphash2{size}=$5; $tmphash2{filename}=$6; push (@{$tmphash->{output}},\%tmphash2); # print "Result REGEX: $tmphash2{inode}\n"; } #else #{ die "No REGEX match on output line\n".$_; #} } bless $tmphash,$classname; } sub getdevice { #Returns the device my ($self,%args)=@_; return $self->{device} } sub getundeletelist { #Returns the list of files which can be undeleted on the device my ($self,%args)=@_; return @{$self->{output}}; } sub undeletefile { #Input is a numer and optionally a filename and directory #With this input, the filename on that number of the array OUTPUT +is undeleted #The output of NTFSUNDELETE is sent back to the caller my ($self,%args)=@_; die "illegal numer of file to undelete\n" unless defined($args{num +ber}); die "illegal numer of file to undelete\n" unless @{$self->{output} +}>=$args{number}; my $number = $args{number}; my %tmphash = %{$self->{output}[$number]}; my $directory=$args{directory}||"~"; my $filename=$args{filename}||"undeleted.xxx"; print "INODE: $tmphash{inode}\n"; print "COMMAND: ntfsundelete $self->{device} -u -i $tmphash{inode} + -o $filename -d $directory\n"; #Run the command and redirect STERR to STDOUT my @output = `ntfsundelete $self->{device} -u -i $tmphash{inode} - +o $filename -d $directory 2>&1`; chdir $directory; #Change ownder to user if parameter is present if ($args{user}) { my @output2 = `chown $args{user}:$args{user} ./$filename 2>&1` +; } my @output3 = `chmod 755 ./$filename 2>&1`; # print"CHOWN: @output2\n"; # print"CHMOD: @output3\n"; return @output; } 1;