2 # compute the blocks used by a file
4 # computeblocklists [options] <files...>
6 # --padstart NUM, --padend NUM, --verbose
9 # <file base name> <size> <blocksize> <block numbers...>
11 # a block is either a number or a range (start-end)
14 ################################################################
16 # Copyright (c) 1995-2014 SUSE Linux Products GmbH
18 # This program is free software; you can redistribute it and/or modify
19 # it under the terms of the GNU General Public License version 2 or 3 as
20 # published by the Free Software Foundation.
22 # This program is distributed in the hope that it will be useful,
23 # but WITHOUT ANY WARRANTY; without even the implied warranty of
24 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 # GNU General Public License for more details.
27 # You should have received a copy of the GNU General Public License
28 # along with this program (see the file COPYING); if not, write to the
29 # Free Software Foundation, Inc.,
30 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
32 ################################################################
36 my ($opt_padstart, $opt_padend, $opt_verbose, $opt_manifest, $opt_mani0);
40 if ($ARGV[0] eq '--padstart') {
42 $opt_padstart = shift @ARGV;
45 if ($ARGV[0] eq '--padend') {
47 $opt_padend = shift @ARGV;
50 if ($ARGV[0] eq '--verbose' || $ARGV[0] eq '-v') {
55 if ($ARGV[0] eq '-0') {
60 if ($ARGV[0] eq '--manifest') {
62 $opt_manifest = shift @ARGV;
68 print "\n"x$opt_padstart if $opt_padstart;
71 if ($opt_manifest eq '-') {
72 open(MANIFEST, '<&STDIN') || die("STDIN dup: $!\n");
74 open(MANIFEST, '<', $opt_manifest) || die("$opt_manifest: $!\n");
82 } elsif ($opt_manifest) {
86 last unless defined $file;
90 last unless defined $file;
97 $n =~ s/([\000-\037 %])/sprintf("%%%02X", ord($1))/ges;
99 print STDERR "$file\n" if $opt_verbose && !($opt_verbose == 1 && $file =~ /^KIWI\/.*\//);
100 my $c = readlink($file);
101 die("$file: readlink: $!\n") unless defined $c;
102 if ("/$c/" =~ /\/\.?\//s) {
103 print STDERR "$file: bad symlink ($c) ignored\n";
106 if ("/$c/" =~ /^(\/\.\.)+\/(.*?)$/s) {
107 my ($head, $tail) = ($1, $2);
108 if (("/$tail/" =~ /\/\.\.\//s) || (($head =~ y!/!!) > ($file =~ y!/!!))) {
109 print STDERR "$file: bad symlink ($c) ignored\n";
113 if ("/$c/" =~ /\/\.\.\//s) {
114 print STDERR "$file: bad symlink ($c) ignored\n";
118 $c =~ s/([\000-\037 %])/sprintf("%%%02X", ord($1))/ges;
122 print STDERR "$file\n" if $opt_verbose && $opt_verbose > 1;
129 print STDERR "$file\n" if $opt_verbose && !($opt_verbose == 1 && $file =~ /^KIWI\/.*\//);
131 if (!open(F, '<', $file)) {
132 print STDERR "$file: $!";
138 my $st_size = $stat[7];
146 ioctl(F, 2, $bsize) || ioctl(F, 536870914, $bsize) || die("FIGETBSZ: $!\n");
147 $bsize = unpack("L", $bsize);
148 die("$file: empty blocksize\n") unless $bsize != 0;
150 print "f $n $st_size $bsize";
151 my $blocks = int(($st_size+$bsize-1)/$bsize);
152 my ($firstblock, $lastblock);
153 for ($b = 0; $b < $blocks; ++$b) {
154 my $block = pack('I', $b);
155 if (not defined ioctl(F, 1, $block)) {
156 if (not defined ioctl(F, 536870913, $block)) {
160 $block = unpack('I', $block);
161 if (!$firstblock && defined($firstblock)) {
162 # last block was hole
164 $lastblock++; # count holes, 0-2 means three hole blocks
166 # switch back from 'hole mode' into normal mode
167 printf "-$lastblock" if defined($firstblock) && $firstblock != $lastblock;
169 $firstblock = $lastblock = $block;
173 if (!$firstblock || $lastblock + 1 != $block) {
175 printf "-$lastblock" if defined($firstblock) && $firstblock != $lastblock;
177 $firstblock = $block;
182 printf "-$lastblock" if defined($firstblock) && $firstblock != $lastblock;
187 print "\n"x$opt_padend if $opt_padend;