-
Notifications
You must be signed in to change notification settings - Fork 1
/
dumpbtree.pl
executable file
·75 lines (63 loc) · 2.12 KB
/
dumpbtree.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#!perl -w
use strict;
$|=1;
use Dumpvalue;
use Bitmap;
use HFSUtils;
use GetOpt::Long;
use CatalogParser;
use ExtentParser;
use AttributeParser;
use IO::File;
use HFSBtree;
my $d= new Dumpvalue;
sub usage {
return "Usage: dumpbtree file.btree [block.bitmap [node.bitmap]]\n";
}
my $filename= shift || die usage();
my $parser= ($filename =~ /cat/i)?CatalogParser->new():
($filename =~ /attr/i)?AttributeParser->new():
($filename =~ /ext/i)?ExtentParser->new():die "unknown type\n";
# http://www.opensource.apple.com/darwinsource/10.4.9.x86/xnu-792.18.15/bsd/hfs/hfs_format.h
#
#my @nodestats;
my $fh= IO::File->new($filename, "r") or die "$filename: $!\n";
binmode $fh;
my $bt= HFSBtree->new($fh, $parser);
if (-s $filename != $bt->{btree}{totalNodes} * $bt->{btree}{nodeSize}) {
printf("WARN: filesize: %08lx, hdr: %08lx\n", -s $filename, $bt->{btree}{totalNodes} * $bt->{btree}{nodeSize});
}
for (my $nodenr=0 ; $nodenr < $bt->{btree}{totalNodes} ; $nodenr++) {
my $nodedata= eval { $bt->readNode($nodenr) }; last if $@;
next if ($nodedata =~ /^\x00{14}/);
my $node= $bt->parseNode($nodedata);
$node->{id}= $nodenr;
#printf("---- node%08x type=%02x prev=node%08lx next=node%08lx height=%d nr=%d\n", $nodenr, $node->{kind}, $node->{bLink}, $node->{fLink}, $node->{height}, $node->{numRecords});
# $nodestats[$nodenr] |= 0x40 if $node->{kind}==255;
# $nodestats[$nodenr] |= 0x80 if $node->{kind}==0;
# $nodestats[$nodenr] |= 0x100 if $node->{kind}==1;
# $nodestats[$nodenr] |= 0x200 if $node->{kind}==2;
$bt->dumpNode($node);
#$bt->leafDump($node);
}
print $parser->dumpStats();
if (@ARGV) {
$parser->getBlockBitmap()->save(shift);
}
# 1: flink
# 2: blink
# 4: isroot
# 8: firstleaf
# 10: lastleaf
# 20: pointer
# 40: leaf
# 80: index
#100: header
#200: mapnode
#400: in_map
# printf("node usage\n");
# for (my $nr=0 ; $nr<@nodestats ; $nr++) {
# if (defined $nodestats[$nr]) {
# printf("node%08lx: usage: %012b\n", $nr, $nodestats[$nr]);
# }
# }