#! /usr/bin/perl
# Check if locks get stuck
# anders.nordby@aftenposten.no, 2007-08-24
#
# 2009-03-03: Fix for symlinks. Oops.
# 2009-03-13: Fix to notice if lock directory is not readable. Oops.

use Getopt::Std;

getopts('d:w:c:D');

if (!$opt_d || !$opt_w || !$opt_c) {
	print "Usage: checklocks -d <directories..> -w <warning time> -c <critical time>\n";
	print "\nUse double quots (\"\") and space separation for several directories.\n";
	print "Time is in seconds.\n";
	exit(3);
}

$crittxt = "";
$warntxt = "";
$oktxt = "";
$myage = scalar(time);
%files=();

for $dir (split(/ /, $opt_d)) {
	if ( -d $dir && -r $dir ) {
		if ($opt_D) { print "DEBUG: Checking dir $opt_d.\n"; }
		opendir(DIR, $dir);
		for $file (readdir(DIR)) {
			next if ($file eq "." || $file eq "..");
			$filep = "$dir/$file";
			if ($opt_D) { print "DEBUG: Adding file $file.\n"; }
			if ( -l $filep ) {
				$files{"$filep"} = (lstat($filep))[9];
			} else {
				$files{"$filep"} = (stat($filep))[9];
			}
		}
		closedir(DIR);
	} else {
		print "$dir is not a directory, or is not readable.\n";
		exit(3);
	}
}

if ($opt_D) {
	foreach $file (keys %files) {
		print "Fant fil: $file\n";
	}
}

if (!%files) {
	print "No locks found in directorie(s): $opt_d. Fine.\n";
	exit(0);
}

if ($opt_D) { print "My age: $myage\n"; }
foreach $file (keys %files) {
	$age = $myage - $files{"$file"};
	if ($opt_D) { print "DEBUG: $file: " . $files{"$file"} . " (age $age)\n"; }
	if ($age > $opt_c) {
		$crittxt .= "$file ($age". "s) ";
	} elsif ($age > $opt_w) {
		$warntxt .= "$file ($age". "s) ";
	} else {
		$oktxt .= "$file ($age". "s) ";
	}
}

$crittxt =~ s@ $@@;
$warntxt =~ s@ $@@;
if ($crittxt ne "") {
	print "Old lock files found: $crittxt";
	if ($warntxt ne "") {
		print " $warntxt";
	}
	print "\n";
	exit(2);
} elsif ($warntxt ne "") {
	print "Old lock files found: $warntxt\n";
	exit(1);
} else {
	print "Lock files found, but they are not too old: $oktxt\n";
	exit(0);
}
