rpmsafereduce: +$IGNORE_D,die->carp
[nethome.git] / bin / rpmsafereduce
1 #! /usr/bin/perl
2 # rpmsafe|sort -u|rpmsafereduce >EXCLUDE-FILELIST
3 use Carp;
4 my $IGNORE_D;
5 #$IGNORE_D=1; # Do not backup directory entry itself even if it is missing in rpms. 581692 -> 37998 vs. 44248
6 use strict;
7 use warnings;
8 sub slashes($) {
9   my($s)=@_;
10   (my $sl=$s)=~tr{/}{}cd;
11   $sl=length $sl;
12   $sl>=1 or carp "<$s>";
13   return $sl;
14 }
15 my(%d,%f,%t);
16 my $l;
17 while (<>) {
18   chomp;
19   next if $_ eq "/";
20   carp $_ if m{//};
21   m{^/} or carp $_;
22   carp $_ if m{/$};
23   carp "sort -u: $l >= $_" if $l && $l ge $_;
24   $l=$_;
25   my $sl=slashes $_;
26   $d{$_}=$sl if -d;
27   $f{$_}=$sl if -f;
28   s{/[^/]*$}{} or carp $_;
29   $d{$_}=$sl-1 if $IGNORE_D && $_ ne "";
30   $t{$_}=1 if $d{$_};
31 }
32 my $time;
33 while (%t) {
34   my @t=keys(%t);
35   %t=();
36   #warn((@t+0)."\n");
37   @t=sort { ($f{$b}||$d{$b}) <=> ($f{$a}||$d{$a}) || $a cmp $b; } @t;
38   while (@t) {
39     if (defined $time&&time()!=$time) {
40       $time=time();
41       print STDERR (@t+0)."    \r";
42     }
43     my $t=shift @t;
44     next if !$d{$t}&&!$f{$t};
45     opendir DIR,$t or carp "$t: $!";
46     my $ok=1;
47     local $_;
48     my @d;
49     for my $d (readdir DIR) {
50       push @d,$d;
51       next if $d eq ".";
52       next if $d eq "..";
53       next if $f{"$t/$d"};
54       next if $d{"$t/$d"};
55       $ok=0;
56       last;
57     }
58     closedir DIR or carp "$t: $!";
59     next if !$ok;
60     for my $d (@d) {
61       delete $f{"$t/$d"};
62       delete $t{"$t/$d"};
63     }
64     $f{$t}=slashes $t;
65     $t=~s{/[^/]*$}{} or carp $t;
66     $d{$t}=slashes $t if $IGNORE_D && $t ne "";
67     $t{$t}=1 if $d{$t};
68   }
69 }
70 for my $f (sort keys(%f)) {
71   print "$f\n";
72 }