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 each 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 geweigerd/); 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{number}); 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;