Add the tar.bz2 archive
[dvb-osmc.git] / linux / use_dir.pl
blobb461ec5930855d8a1184a6a7a0bec8e18951dfdb
1 #!/usr/bin/perl
2 use strict;
3 use File::Find;
4 use File::Path;
5 use File::Copy;
6 use Fcntl ':mode';
7 use Getopt::Long;
8 use Digest::SHA;
10 my $silent = 0;
11 my $debug = 0;
12 my $recheck = 0;
13 my $get_patched = 0;
14 GetOptions( "--debug" => \$debug,
15 "--silent" => \$silent,
16 "--recheck" => \$recheck,
17 "--get_patched" => \$get_patched,
20 my $dir = shift;
22 my $ctlfile = ".linked_dir";
23 my $patchfile = ".patches_applied";
25 my $sync_patched = 0;
26 my %dirs;
27 my %files;
28 my $patches_applied;
30 #########################################
31 # Control info stored at the control file
32 my $path;
33 my %fhash;
34 my %fhash_patched;
35 #########################################
37 sub read_ctlfile()
39 my $line;
41 open IN, $ctlfile or return;
42 while (<IN>) {
43 next if (m/^\s*\#/);
44 next if (m/^\n$/);
45 if (m/^path:\s*([^\s]+)/) {
46 $path = $1;
47 } elsif (m/^hash\:\s*([^\s]+)\s*=\s*([^\s]+)/) {
48 $fhash{$1} = $2;
49 } elsif (m/^hash_patched\:\s*([^\s]+)\s*=\s*([^\s]+)/) {
50 $fhash_patched{$1} = $2;
51 } else {
52 printf("Parse error on this line of $ctlfile:\n\t$_");
53 die;
56 close IN;
59 sub write_ctlfile()
61 open OUT, ">$ctlfile" or print "Error: Can't write to $ctlfile\n";
62 print OUT "path: $path\n";
63 foreach my $file (keys %fhash) {
64 printf OUT "hash: %s=%s\n", $file, $fhash{$file};
66 foreach my $file (keys %fhash_patched) {
67 printf OUT "hash_patched: %s=%s\n", $file, $fhash_patched{$file};
69 close OUT;
72 sub add_dirs($)
74 my $data = shift;
75 my @dirs = split(' ', $data);
77 foreach my $val (@dirs) {
78 $dirs{$val} = 1;
82 sub add_files($)
84 my $data = shift;
85 my @dirs = split(' ', $data);
87 foreach my $val (@dirs) {
88 $files{$val} = 1;
92 sub get_file_dir_names()
94 open IN, "Makefile" or die "Couldn't open Makefile";
95 while (<IN>) {
96 if (m/^\s*TARDIR\s*[\+\:]*=\s*([A-Za-z_].*)/) {
97 add_dirs($1);
98 } elsif (m/^\s*TARFILES\s*[\+\:]*=\s*([A-Za-z_].*)/) {
99 add_files($1);
102 close IN;
106 sub hash_calc($)
108 my $file = shift;
110 my $ctx = Digest::SHA->new;
112 my $rc = open INHASH, $file;
113 if (!$rc) {
114 print "Couldn't open file $file\n" if ($debug);
115 return 0;
117 $ctx->addfile(*INHASH);
118 my $digest = $ctx->hexdigest;
119 close INHASH;
121 return $digest;
124 sub sync_files($)
126 my $file = shift;
127 my $path = $file;
128 my $check_hash;
129 my $need_sync;
130 my $filehash;
131 my $cpfilehash;
132 my $patched_file;
134 $path =~ s,/[^/]+$,,;
136 $filehash = hash_calc("$dir/$file");
137 $need_sync = 1 if ($filehash ne $fhash{$file});
139 if (!$need_sync && $recheck) {
140 $cpfilehash = hash_calc("$file");
141 if ($patches_applied && exists($fhash_patched{$file})) {
142 $patched_file = 1;
143 $need_sync = 1 if ($cpfilehash ne $fhash_patched{$file});
144 } else {
145 $need_sync = 1 if ($cpfilehash ne $fhash{$file});
149 if ($need_sync) {
150 printf "Sync'ing file $file (orig = %s, copy = %s, patched = %s)\n",
151 $filehash, $cpfilehash, $fhash_patched{$file} if ($debug || $recheck);
153 if (exists($fhash_patched{$file})) {
154 $sync_patched = 1;
155 } else {
156 $fhash{$file} = $filehash;
157 mkpath($path);
158 copy("$dir/$file", $file);
160 } else {
161 print "Skipping file $file, as is already synchronized\n" if ($debug);
165 sub get_patched_files()
167 my %files;
169 open IN, $patchfile or return %files;
171 # Those files are always patched to add warnings about the usage of experimental version
172 $files{"drivers/media/dvb-core/dvbdev.c"} = 1;
173 $files{"drivers/media/v4l2-core/v4l2-dev.c"} = 1;
174 $files{"drivers/media/rc/rc-main.c"} = 1;
176 while (<IN>) {
177 next if (/^\s*#/);
179 if (m/(.*)\n/) {
180 print ("Backport ../backports/$1 touch(es) file(s):\n") if ($debug);
181 open IN2, "lsdiff -h --strip 1 ../backports/$1 |";
182 while (<IN2>) {
183 my $f = $_;
184 $f =~ s/\n//;
185 $files{$f} = 1;
186 print ("\t$f\n") if ($debug);
188 close IN2;
191 close IN;
193 return %files;
196 sub sync_patched_files()
198 my %patches = get_patched_files();
199 return if (!%patches);
201 foreach my $file (keys %patches) {
202 printf "sync patched file $file\n";
203 $fhash{$file} = hash_calc("$dir/$file");
204 mkpath($path);
205 copy("$dir/$file", $file);
207 close IN;
210 sub get_patched_hashes()
212 my %patches = get_patched_files();
213 return if (!%patches);
215 foreach my $file (keys %patches) {
216 $fhash_patched{$file} = hash_calc("$file");
217 printf "Hash for patched file $file = %s\n", $fhash_patched{$file} if ($debug);
219 close IN;
222 sub remove_deleted()
224 my $file = $File::Find::name;
225 my $mode = (stat($file))[2];
227 return if ($mode & S_IFDIR);
229 return if ($file =~ /^\./);
230 return if ($file =~ /\.mod\.c/);
232 if ($file =~ /Makefile$/ || $file =~ /Kconfig$/ || $file =~ /\.[ch]$/ ) {
233 if (! -e "$dir/$file") {
234 printf "Removing file $file\n" if (!$silent);
235 delete $fhash{$file} if exists($fhash{$file});
236 delete $fhash_patched{$file} if exists($fhash_patched{$file});
237 unlink $file;
238 return;
243 sub parse_dir()
245 my $file = $File::Find::name;
246 my $mode = (stat($file))[2];
248 return if ($mode & S_IFDIR);
250 $file =~ s,^($dir/),,;
252 return if ($file =~ /^\./);
253 return if ($file =~ /\.mod\.c/);
255 if ($file =~ /Makefile$/ || $file =~ /Kconfig$/ || $file =~ /\.[ch]$/ ) {
256 sync_files $file;
257 return;
260 printf "Skipping bogus file $file\n" if ($debug);
263 sub sync_dirs($)
265 my $subdir = shift;
267 print "sync dir: $subdir\n" if (!$silent);
268 find({wanted => \&parse_dir, no_chdir => 1}, "$dir/$subdir");
269 find({wanted => \&remove_deleted, no_chdir => 1}, "$subdir");
272 sub sync_all()
274 foreach my $val (keys %files) {
275 print "sync file: $val\n" if (!$silent);
276 sync_files($val);
278 foreach my $val (keys %dirs) {
279 sync_dirs($val);
283 sub sync_kernel_version()
285 my ($source_v4l_version, $a, $b, $c, $ver);
287 open IN, "$dir/Makefile" or die "Can't find $dir/Makefile";
288 while (<IN>) {
289 $a=$1 if (m/^\s*VERSION\s*=\s*(\d+)/);
290 $b=$1 if (m/^\s*PATCHLEVEL\s*=\s*(\d+)/);
291 $c=$1 if (m/^\s*SUBLEVEL\s*=\s*(\d+)/);
293 close IN;
294 $source_v4l_version = ((($a) << 16) + (($b) << 8) + ($c));
296 if (open IN, "kernel_version.h") {
297 while (<IN>) {
298 $ver=$1 if (m/^#define\s*V4L2_VERSION* \s*(\d+)/);
300 close IN;
303 if ($ver ne $source_v4l_version) {
304 open OUT,">kernel_version.h";
305 printf OUT "#define V4L2_VERSION %d\n", $source_v4l_version;
306 close OUT;
310 # Main
312 if (!$dir) {
313 read_ctlfile();
314 die "Please provide a directory to use" if !($path);
315 $dir = $path;
317 printf "Syncing with dir $dir\n";
318 } else {
319 read_ctlfile();
321 sync_kernel_version();
323 if ($path ne $dir) {
324 $path = $dir;
325 %fhash = ();
328 $patches_applied = 1 if (-e $patchfile);
330 if ($get_patched && $patches_applied) {
331 get_patched_hashes();
332 } else {
333 get_file_dir_names();
334 sync_all();
336 if ($sync_patched) {
337 sync_patched_files();
338 unlink $patchfile;
342 write_ctlfile();
343 system "git --git-dir $dir/.git log --pretty=oneline -n3 |sed -r 's,([\x22]),,g; s,([\x25\x5c]),\\1\\1,g' >git_log"