[build] copy qemus from server not for local build
[opensuse:build.git] / computeblocklists
1 #!/usr/bin/perl -w
2 # compute the blocks used by a file
3 # usage:
4 # computeblocklists [options] <files...>
5 # options:
6 # --padstart NUM, --padend NUM, --verbose
7 #
8 # output:
9 # <file base name> <size> <blocksize> <block numbers...>
10 #
11 # a block is either a number or a range (start-end)
12 #
13 # TODO: instead of printing zeroes for each block in a hole use
14 # something like 0*num
15
16 use strict;
17
18 my ($opt_padstart, $opt_padend, $opt_verbose);
19
20 while (@ARGV)  {
21   if ($ARGV[0] eq '--padstart') {
22     shift @ARGV;
23     $opt_padstart = shift @ARGV;
24     next;
25   }
26   if ($ARGV[0] eq '--padend') {
27     shift @ARGV;
28     $opt_padend = shift @ARGV;
29     next;
30   }
31   if ($ARGV[0] eq '--verbose' || $ARGV[0] eq '-v') {
32     shift @ARGV;
33     $opt_verbose = 1;
34     next;
35   }
36   last;
37 }
38
39 if($opt_padstart) {
40   print "\n"x$opt_padstart;
41 }
42
43 for my $file (@ARGV) {
44   next unless -f $file;
45   print STDERR "$file\n" if $opt_verbose;
46   my $n = $file;
47   $n =~ s/.*\///;
48
49   if(!open(F, '<', $file)) {
50     print STDERR "$file: $!";
51     next;
52   }
53
54   my $bsize = 'xxxx';
55   ioctl(F, 2, $bsize) || ioctl(F, 536870914, $bsize) || die("FIGETBSZ: $!\n");
56   $bsize = unpack("L", $bsize);
57
58   my @stat = stat(F);
59   my ($st_size, $st_blocks) = ($stat[7], $stat[11], $stat[12]);
60
61   my $blocks = int(($st_size+$bsize-1)/$bsize);
62
63   print "$n $st_size $bsize ";
64
65   my ($firstblock, $lastblock);
66   for ($b = 0; $b < $blocks; ++$b) {
67     my $block = pack('I', $b);
68     if(not defined ioctl(F, 1, $block)) {
69         if(not defined ioctl(F, 536870913, $block)) {
70             die "$file: $!";
71         }
72     }
73     $block = unpack('I', $block);
74     if($b == 0) {
75       print "$block";
76       $firstblock = $block;
77     } else {
78       # blocks are non-contiguous
79       if($lastblock+1 != $block) {
80         # check if we skipped some that form a range
81         if($firstblock != $lastblock) {
82           printf "-$lastblock";
83         }
84         print " $block";
85         $firstblock = $block;
86       }
87       # last block, check if contiguous
88       if($b+1==$blocks && $lastblock+1 == $block) {
89         print "-$block";
90       }
91     }
92     $lastblock = $block;
93   }
94   close F;
95   print "\n";
96 }
97
98 if($opt_padend) {
99   print "\n"x$opt_padend;
100 }