#############################################################################
#
#  Copyright (c) 1992 Comdisco Systems Inc.
#  All rights reserved.
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions
#  are met:
#  1. Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
#  2. Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#  3. All advertising materials mentioning features or use of this software
#     must display the following acknowledgement:
#       This product includes software developed by the Comdisco Systems Inc.
#  4. The name of Comdisco may not be used to endorse or promote products
#     derived from this software without specific prior written permission.
#
#  THIS SOFTWARE IS PROVIDED BY THE COMDISCO SYSTEMS INC ``AS IS'' AND
#  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
#  ARE DISCLAIMED.  IN NO EVENT SHALL COMDISCO SYSTEMS INC BE LIABLE
#  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
#  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
#  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
#  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
#  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
#  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#  SUCH DAMAGE.
#
# This copyright notice derrived from material copyrighted by the Regents
# of the University of California.
#
#############################################################################

sub check_lock_validity
{
	local($lockfile) = @_;
	local($t);
	local($pid,$host,$prog);
	local($rsh);
	local(*PS);
	local($goodps);
	local($lock_verified);

	if (-e $lockfile && ! -l $lockfile) {
		print "Lock is a file; cannot be verfied\n" unless $opt_quiet;
		return undef;
	}
	&lock_file($lockfile,'exclusive',0);
	$t = readlink($lockfile);
	if ($t =~ m!locked by process (\d+) on (\S+) \((.+)\)$!) {
		($pid,$host,$prog) = ($1,$2,$3);
		if (defined($locks'deadproc{$host,$pid}) && 
				$locks'deadproc{$host,$pid}) {
			print "Process $pid ($prog) died; removing lock...\n" unless $opt_quiet;
			unlink($lockfile)
				|| warn "could not unlink $lockfile: $!";
		} else {
			
			chop($hostname = `hostname`) unless $hostname;
			if ($hostname ne $host) {
				$rsh = "rsh $host -n ";
			}
			print "rsh '$rsh'\n" if $locks'debug;
			open(PS,"${rsh}ps axc|") 
				|| die "could not popen ${rsh}ps axc: $!";
			while($_ = <PS>) {
				if (/\s*1\s+.*\sinit$/) {
					$goodps = 1;
				}
				if (/^\s*$pid\s/) {
					$lock_verified = 1;
				}
			}
			close(PS);

			if ($lock_verified) {
				print "Process $pid on $host exists; lock verified.\n" unless $opt_quiet;
			} elsif ($goodps) {
				print "Process $pid ($prog) died; removing lock...\n" unless $opt_quiet;
				$locks'deadproc{$host,$pid} = 1;
				unlink($lockfile)
					|| warn "could not unlink $lockfile: $!";
			} else {
				print "Could not read process table, leaving lock.\n" unless $opt_quiet;
			}

			close(PS);
		}
	} elsif ($t eq "" || $t eq "/") {
		print "Lock $lockfile is corrupt, removing...\n";
		unlink($lockfile)
			|| warn "could not unlink $lockfile: $!";
	} else {
		print "Cannot verify lock: unknown format: '$t'\n" unless $opt_quiet;
	}
	&unlock_file($lockfile);
}

1;