update tizen version to tizen20231130
[tools/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
14 ################################################################
15 #
16 # Copyright (c) 1995-2014 SUSE Linux Products GmbH
17 #
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.
21 #
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.
26 #
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
31 #
32 ################################################################
33
34 use strict;
35
36 my ($opt_padstart, $opt_padend, $opt_verbose, $opt_manifest, $opt_mani0);
37 $opt_verbose = 0;
38
39 while (@ARGV)  {
40   if ($ARGV[0] eq '--padstart') {
41     shift @ARGV;
42     $opt_padstart = shift @ARGV;
43     next;
44   }
45   if ($ARGV[0] eq '--padend') {
46     shift @ARGV;
47     $opt_padend = shift @ARGV;
48     next;
49   }
50   if ($ARGV[0] eq '--verbose' || $ARGV[0] eq '-v') {
51     shift @ARGV;
52     $opt_verbose++;
53     next;
54   }
55   if ($ARGV[0] eq '-0') {
56     shift @ARGV;
57     $opt_mani0 = 1;
58     next;
59   }
60   if ($ARGV[0] eq '--manifest') {
61     shift @ARGV;
62     $opt_manifest = shift @ARGV;
63     next;
64   }
65   last;
66 }
67
68 print "\n"x$opt_padstart if $opt_padstart;
69
70 if ($opt_manifest) {
71   if ($opt_manifest eq '-') {
72     open(MANIFEST, '<&STDIN') || die("STDIN dup: $!\n");
73   } else {
74     open(MANIFEST, '<', $opt_manifest) || die("$opt_manifest: $!\n");
75   }
76 }
77
78 while (1) {
79   my $file;
80   if (@ARGV) {
81     $file = shift @ARGV;
82   } elsif ($opt_manifest) {
83     if ($opt_mani0) {
84       local $/ = "\0";
85       $file = <MANIFEST>;
86       last unless defined $file;
87       $file =~ s/\0$//s;
88     } else {
89       $file = <MANIFEST>;
90       last unless defined $file;
91       chomp $file;
92     }
93   } else {
94     last;
95   }
96   my $n = $file;
97   $n =~ s/([\000-\037 %])/sprintf("%%%02X", ord($1))/ges;
98   if (-l $file) {
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";
104       next;
105     }
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";
110         next;
111       }
112     } else {
113       if ("/$c/" =~ /\/\.\.\//s) {
114         print STDERR "$file: bad symlink ($c) ignored\n";
115         next;
116       }
117     }
118     $c =~ s/([\000-\037 %])/sprintf("%%%02X", ord($1))/ges;
119     print "l $n $c\n";
120     next;
121   } elsif (-d _) {
122     print STDERR "$file\n" if $opt_verbose && $opt_verbose > 1;
123     my @stat = stat(_);
124     print "d $n\n";
125     next;
126   } elsif (!-f _) {
127     next;
128   }
129   print STDERR "$file\n" if $opt_verbose && !($opt_verbose == 1 && $file =~ /^KIWI\/.*\//);
130
131   if (!open(F, '<', $file)) {
132     print STDERR "$file: $!";
133     next;
134   }
135
136   my @stat = stat(F);
137   die unless @stat;
138   my $st_size = $stat[7];
139   if ($st_size == 0) {
140     print "f $n 0\n";
141     close F;
142     next;
143   }
144
145   my $bsize = 'xxxx';
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;
149
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)) {
157         die "$file: $!\n";
158       }
159     }
160     $block = unpack('I', $block);
161     if (!$firstblock && defined($firstblock)) {
162       # last block was hole
163       if (!$block) {
164         $lastblock++;   # count holes, 0-2 means three hole blocks
165       } else {
166         # switch back from 'hole mode' into normal mode
167         printf "-$lastblock" if defined($firstblock) && $firstblock != $lastblock;
168         print " $block";
169         $firstblock = $lastblock = $block;
170       }
171       next;
172     }
173     if (!$firstblock || $lastblock + 1 != $block) {
174       # start of a new run
175       printf "-$lastblock" if defined($firstblock) && $firstblock != $lastblock;
176       print " $block";
177       $firstblock = $block;
178     }
179     $lastblock = $block;
180   }
181   # finish last run
182   printf "-$lastblock" if defined($firstblock) && $firstblock != $lastblock;
183   close F;
184   print "\n";
185 }
186
187 print "\n"x$opt_padend if $opt_padend;