#!/usr/bin/perl
# nuke-old-logs.pl
#
# Search for files recursively under /var/log and remove them.
# This script uses lsof to perform sanity checking and see if
# another process has them open before removing them.
#
# Jan 13, 2007 Jeff Schroeder (jeffschroeder@computer.org)
#
# License: GNU GPL 2

use strict;
use File::Find; # Makes this shizzle 10x easier

my @search_dirs = ("/var/log");

find(\&cleanup, @search_dirs);

sub cleanup {
    my ($dev,$inode,$mode,$nlink,$uid,$gid);
    my $name   = $File::Find::name;
    my $isopen = "0";

    (($dev,$inode,$mode,$nlink,$uid,$gid) = lstat($_));

    # Delete regular writable files last modified more than 10 days ago
    if ((-f _) and (int(-M _) > 10) and (-w _)) {

    # _ is shorthand for the last used file descriptor and is
    # faster because it doesn't do another stat() but uses previous results

        # Use EXTREME caution and make sure some crazy process hasn't been holding onto the log
        open(LSOF, "/usr/bin/lsof -nPFpf $name|") or die "ERROR: Can't open lsof: $!\n";
        while (<LSOF>) {
            # -F is the machine readable lsof arg. fxxxx for file descriptor and pxxxx for pid
            if ((/^f/o) or (/^p/o)) {
                $isopen = 1;
                last;
            }
        }

        if ($isopen ne 1) {
            # If delete fails, send a warn and return to keep from printing false deletion info
            unlink("$name") or warn("Unable to remove $name: $!\n") and return;
            print "$name", " " x (60 - length($name)), "removed!\n";
        } else {
            print "$name", " " x (60 - length($name)), "is currently open!\n";
        }
    }
}
