5
# --------------------------------------------------------------------------------
7
sub getModtimeAndSize($) {
8
my ($file_or_dir) = @_;
9
if (-f $file_or_dir or -d $file_or_dir) {
10
my @st = stat($file_or_dir);
11
if (not @st) { die "can't stat '$file_or_dir' ($!)"; }
12
return ($st[9],$st[7]); # (stamp,size)
14
return (0,0); # does not exist -> use (epoch,zerosize)
17
sub getAgeAndSize($) {
18
my ($file_or_dir) = @_;
19
my ($mod,$size) = getModtimeAndSize($file_or_dir);
20
return (time-$mod,$size);
23
# --------------------------------------------------------------------------------
25
sub scanPatches($$\@) {
26
my ($patchDir,$mask,$patch_r) = @_;
28
opendir(DIR,$patchDir) || die "can't read directory '$patchDir' (Reason: $!)";
29
foreach (readdir(DIR)) { if ($_ =~ $reg) { push @$patch_r, $_; } }
33
sub patchesDiffer($$$) {
34
my ($patchDir,$patch,$otherpatch) = @_;
35
my $diff = `diff $patchDir/$patch $patchDir/$otherpatch | wc -l`;
39
sub getOldDuplicates($\@\%\%) {
40
my ($patchDir,$patch_r,$age_r,$size_r) = @_;
44
foreach my $patch (@$patch_r) {
45
my $size = $$size_r{$patch};
46
my $otherpatch = $size2patch{$size};
47
if (defined $otherpatch) { # got another patch with same size
48
my $diff = patchesDiffer($patchDir,$patch,$otherpatch);
52
else { # no diff -> removed older
53
if ($$age_r{$otherpatch} > $$age_r{$patch}) {
54
push @oldDups, $otherpatch;
55
$size2patch{$size} = $patch;
58
push @oldDups, $patch;
63
$size2patch{$size} = $patch;
71
if ($size<1024) { $size.'b'; }
73
$size = int($size/1024);
74
if ($size<1024) { $size.'k'; }
76
$size = int($size/1024);
77
if ($size<1024) { $size.'M'; }
79
$size = int($size/1024);
86
sub countAndSize($$$) {
87
my ($name,$count,$size) = @_;
88
return $count.' '.$name.' patches ('.readableSize($size).') ';
92
my $args = scalar(@ARGV);
94
print "Usage: arb_cleanup_patches.sh name hours minkeep\n";
95
print " deletes all patches matching 'name_*.patch' if\n";
96
print " - they are older than 'hours' and\n";
97
print " - at least 'minkeep' patches remain present.\n";
98
die "missing arguments";
101
my $mask = $ARGV[0].'.*\.patch';
102
my $olderThanHours = $ARGV[1];
103
my $minKeep = $ARGV[2];
105
my $ARBHOME = $ENV{ARBHOME};
106
if (not defined $ARBHOME) { die "environment variable 'ARBHOME' is not defined"; }
108
my $patchDir = $ARBHOME.'/patches.arb';
109
if (not -d $patchDir) { die "directory '$patchDir' does not exist"; }
113
scanPatches($patchDir,$mask,@patch);
117
foreach (@patch) { ($age{$_},$size{$_}) = getAgeAndSize($patchDir.'/'.$_); }
119
my %unlink_patch = (); # key=patchname, value=why unlink
121
my @oldDups = getOldDuplicates($patchDir,@patch,%age,%size);
122
foreach (@oldDups) { $unlink_patch{$_} = 'duplicate'; }
125
@patch = sort { $age{$a} <=> $age{$b}; } @patch;
127
my $olderThanSeconds = $olderThanHours*60*60;
128
my $patchCount = scalar(@patch);
130
for (my $i=$minKeep; $i<$patchCount; $i++) {
131
my $patch = $patch[$i];
132
if ($age{$patch}>$olderThanSeconds) { $unlink_patch{$patch} = 'old'; }
136
my $unlinked_size = 0;
138
foreach (@patch) { $all_size += $size{$_}; }
140
foreach (sort keys %unlink_patch) {
141
my $fullPatch = $patchDir.'/'.$_;
142
unlink($fullPatch) || die "Failed to unlink '$fullPatch' (Reason: $!)";
143
print "- unlinked ".$unlink_patch{$_}." '$_'\n";
144
$unlinked_size += $size{$_};
149
my $unlinked_patches = scalar(keys %unlink_patch);
150
my $all_patches = scalar(@patch);
152
if ($unlinked_patches>0) {
153
my $left_patches = $all_patches - $unlinked_patches;
154
my $left_size = $all_size - $unlinked_size;
156
$summary .= countAndSize('removed',$unlinked_patches,$unlinked_size);
157
$summary .= countAndSize('kept',$left_patches,$left_size);
160
$summary .= countAndSize('existing',$all_patches,$all_size);
167
if ($@) { die "arb_cleanup_patches.pl: Error: $@\n"; }