#! /usr/bin/perl

# locker - a utility to run a command under the protection of a file lock
# Dave Plonka, Mar  5 1998

require 5.004;
require 'getopts.pl';
use Fcntl ':flock';
use POSIX; # strftime

$format = "%b %d %H:%M:%S"; # format argument to strftime

$script = $0;
$script =~ s:^.*/::;

if (!&Getopts("e:s:nvV") || !($opt_e || $opt_s)) {
   print STDERR <<_EOF_
usage: $script < -e file | -s file > [ -n ] command [ args ... ]
                 -e file - lock specified file for exclusive (write) access
                 -s file - lock specified file for shared (read) access
                 -n      - do an "non-blocking" attempt to lock specified file 
_EOF_
   ;
   exit 2
}

if ($opt_e) {
   $file = $opt_e;
   open(LOCK, "+<$file") || die "open \"$file\" for update failed: $!\n";
   $operation = LOCK_EX;
} else { # $opt_s
   $file = $opt_s;
   open(LOCK, "<$file") || die "open \"$file\" for read failed: $!\n";
   $operation = LOCK_SH;
}

if ($opt_n) {
   $operation |= LOCK_NB;
}

if (!flock(LOCK, $operation)) {
   print(STDERR strftime($format, localtime), " - \"@ARGV\" - ") if $opt_v;
   die "flock failed: $!\n"
}

print("system \"@ARGV\"\n") if $opt_V;

$saved = int(system("@ARGV")/256);

print(strftime($format, localtime), " - \"@ARGV\" - exit: ", $saved, "\n") if $opt_v;

if (!flock(LOCK, LOCK_UN)) {
   print(STDERR &ftime(time), " - \"@ARGV\" - ") if $opt_v;
   warn "flock (unlock) failed: $!\n"
}

exit $saved
