#!/usr/bin/perl use strict; use Math::BigInt; sub ntfscluster { my ($start, $end, $device) = @_; my @results; my @out = `ntfscluster -s${start}-${end} $device 2>&1`; for(@out) { next if /^Error reading inode /; push @results, $_ if /^Inode /; print STDERR $_; } return @results; } sub find { my $lf = shift; my $device = shift; my $start_sector = shift; my $end_sector = shift; my $sector_mult = shift; my @ranges; open LF,"<$lf" or die("cannot open file: $lf\n"); foreach() { my $start = new Math::BigInt($_)*$sector_mult; my $size = new Math::BigInt($sector_mult); my $end = $start + $size - 1; next if $start > $end_sector; next if $end < $start_sector; $start = $start_sector if $start < $start_sector; $end = $end_sector if $end > $end_sector; $start -= $start_sector; $end -= $start_sector; if ((@ranges > 0) && ($ranges[@ranges-1]->[1] + 1 == $start)) { $ranges[@ranges-1]->[1] = $end; } else { push @ranges, [ $start, $end ]; } } close LF; my @results; push @results, ntfscluster(@$_, $device) for @ranges; my $prev = ''; @results = grep($_ ne $prev && (($prev) = $_), sort @results); return @results; } die("Usage: $0 log_file device start_sector end_sector [badblocks_sector_size] [sector_size]\n") if @ARGV < 4; my $lf = $ARGV[0]; my $device = $ARGV[1]; my $start_sector = $ARGV[2]; my $end_sector = $ARGV[3]; my $badblocks_sector_size = $ARGV[4] || 512; my $sector_size = $ARGV[5] || 512; my $sector_mult = $badblocks_sector_size / $sector_size; die("Badblocks sector size ($badblocks_sector_size) must be divisible by sector size ($sector_size)\n") if $badblocks_sector_size % $sector_size; my @results = find($lf, $device, $start_sector, $end_sector, $sector_mult); print "\nSCANNING RESULTS:\n\n"; print for @results;