sub verify_torrent { my($filename, $basepath) = @_; my $ref = _slurp($filename); my $plen = $ref->{info}->{'piece length'}; my $sha = $ref->{info}->{pieces}; my $files = []; if(ref($ref->{info}->{files}) eq 'ARRAY') { foreach my $fref (@{$ref->{info}->{files}}) { push(@$files, {path=>join("/", @{$fref->{path}}), length=>$fref->{length}}); } } else { push(@$files, {path=>$ref->{info}->{name}, length=>$ref->{info}->{length}}); } my $file_index = 0; my $this_path = undef; my $cnt_good = 0; my $cnt_bad = 0; my $badfiles = {}; for(my $i=0; $i 0) { my $src_ref = $files->[$file_index] or last; # got all pieces if($src_ref->{path} ne $this_path) { # new file -> must update FH close(FH); $this_path = $src_ref->{path}; my $vfs = join("/",$basepath, $this_path); open(FH, "<", join("/",$vfs)) or warn "Could not open: $vfs\n"; } my $buff = ''; my $got_bytes = sysread(FH,$buff,$need_bytes); $pbuffer .= $buff; $need_bytes -= $got_bytes; $file_index++ if $got_bytes < 1; } if( unpack("H*",$this_sha) eq sha1_hex($pbuffer) ) { $cnt_good++; } else { $cnt_bad++; $badfiles->{$this_path}++; } print "\rpiece=$this_piece, ok=$cnt_good, bad=$cnt_bad" if $this_piece % 4 == 0; } print "\r".(" " x 32 ); print "\rfound $cnt_bad bad piece(s)\n"; foreach my $this_bad (keys(%$badfiles)) { printf("%-64s : %d bad bytes (%d pieces)\n", $this_bad, $badfiles->{$this_bad}*$plen, $badfiles->{$this_bad}); } }