#/usr/bin/perl (chdir '/usr/spool/news') || die "Can't cd to /usr/spool/news"; $now = time; $| = 1; ($dev,$ino,$mode,$nlink) = stat('.'); &dodir('.',$nlink); exit 0; ############################################################### sub dodir { local($dir,$nlink) = @_; local($dev,$ino,$mode,$time,$cutoff); $dir =~ s#^\./##; # Determine number of days to keep articles in group. $time = 14; $time = 3 if $dir =~ /^(junk|control)/; $time = 8 if $dir =~ /^talk/; $time = 8 if $dir =~ /^rec/; $time = 28 if $dir =~ /^comp/; $time = 10 if $dir =~ /^sci/; $time = 50 if $dir =~ /^comp\.sources\.(unix|misc|bugs)/; $time = 50 if $dir =~ /^comp\.sys\.(sun|pyramid|amiga)/; $time = 50 if $dir =~ /^comp\.windows\.x/; $time = 50 if $dir =~ /^comp\.unix\.wizards/; $time = 60 if $dir =~ /^comp\.lang\.perl/; $time = 50 if $dir =~ /^comp\.bugs/; $time = 50 if $dir =~ /^comp\.sources\.bugs/; $time = 365 if $dir =~ /^proj/; $cutoff = $now - $time * (60 * 60 * 24); # Get all the filenames in current directory handy. # We use readdir() instead of <*> because it doesn't start # a subshell and won't blow up on huge directories. opendir(DIR,'.') || die "Can't open $dir"; local(@filenames) = readdir(DIR); closedir(DIR); # Separate the sheep from the goats. local(@subdirs); local(@articles); for (@filenames) { if (/^\d+$/) { push(@articles,$_); # Possibly a lie, but avoid stat. } else { push(@subdirs,$_); } } # Look for articles to expire. if ($#articles >= 0) { @articles = sort bynumber @articles; # Now the tricksy part. Since the @articles array is # now in age order, we binary search for articles to # expire. At the end of this loop, $min should be # first non-expiring article $max = $#articles; $min = 0; while ($max - $min > 0) { $mid = int(($max + $min) / 2); ($dev,$ino,$mode,$nl,$uid,$gid,$rdev,$size,$atime, $mtime,$ctime) = stat($articles[$mid]); if ($dev == 0) { $min = -1; print STDERR "$dir changed--skipping!\n"; } elsif (-d _) { push(@subdirs, $mid); # Oops, a directory. $min = -1; # Punt this time. } elsif ($mtime >= $cutoff) { # $mid is not expiring $max = $mid; } else { # $mid is expiring $min = $mid + 1; } } # Zap any expired articles. if ($min > 0) { print "$dir: $articles[0] .. $articles[$min-1]\n"; unlink @articles[ 0 .. $min-1 ]; } else { print "$dir: (none)\n"; } } if ($nlink != 2) { # This dir has subdirectories. for (@subdirs) { next if $_ eq '.'; next if $_ eq '..'; $name = "$dir/$_"; ($dev,$ino,$mode,$nlink) = stat($_); next unless -d _; chdir $_ || die "Can't cd to $name"; &dodir($name,$nlink); chdir '..'; } } } sub bynumber { $a <=> $b; }