#! /usr/bin/perl -wT
#
# usage: 
#    check_flexlm.pl license_file
#
# Check available flexlm license managers.
# Use lmstat to check the status of the license server
# described by the license file given as argument.
# Check and interpret the output of lmstat
# and create returncodes and output.
#
# Contrary to the nagios concept, this script takes
# a file, not a hostname as an argument and returns
# the status of hosts and services described in that
# file. Use these hosts.cfg entries as an example
#
#host[anchor]=any host will do;some.address.com;;check-host-alive;3;120;24x7;1;1;1;
#service[anchor]=yodel;24x7;3;5;5;unix-admin;60;24x7;1;1;1;;check_flexlm!/opt/lic/licfiles/yodel_lic
#service[anchor]=yeehaw;24x7;3;5;5;unix-admin;60;24x7;1;1;1;;check_flexlm!/opt/lic/licfiles/yeehaw_lic
#command[check_flexlm]=/some/path/libexec/check_flexlm.pl $ARG1$
#
# Notes:
# - you need the lmstat utility which comes with flexlm.
# - set the correct path in the variable $lmstat.
#
# initial version: 9-10-99 Ernst-Dieter Martin edmt@infineon.com
#
# License: GPL
# $Id: check_flexlm.pl,v 1.6 2003/02/04 06:16:16 sghosh Exp $
#
# lmstat output patches from Steve Rigler/Cliff Rice 13-Apr-2002
# srigler@marathonoil.com,cerice@marathonoil.com


require 5.004;
use strict;
use lib utils.pm ;
use Plugin;
use Plugin::Parameter qw($helpparameterlist $versionparameterlist $filenameparameter
			 $timeoutparameter $verboseparameter);

use vars qw($opt_f $opt_t $opt_v $PROGNAME);

use utils qw(%ERRORS &usage);

my $plugin = new Plugin(-revision => '$Revision: 1.6 $',
			-copyright => "2000 Ernst-Dieter Martin/Karl DeBisschop, 2004 Howard Wilkinson <howard\@cohtech.com>",
			-shortcomment => "Check available flexlm license managers",
			-longcomment => "Flexlm license managers usually run as a single server or three servers and a quorum is needed. The plugin return OK if 1 (single) or 3 (triple) servers are running, CRITICAL if 1(single) or 3 (triple) servers are down, and WARNING if 1 or 2 of 3 servers are running",
			-parameterlists => [ [ $filenameparameter, $timeoutparameter, $verboseparameter ], $helpparameterlist, $versionparameterlist ]);


$ENV{'PATH'}='';
$ENV{'BASH_ENV'}=''; 
$ENV{'ENV'}='';

$plugin->init();

$plugin->start_timeout($opt_t, "Timeout: No Answer from Client");

my $lmstat = $utils::PATH_TO_LMSTAT ;
unless (-x $lmstat ) {
  usage("$PROGNAME UNKNOWN: Cannot find \"lmstat\"\n");
  exit $ERRORS{'UNKNOWN'};
}

print "$opt_f\n" if $opt_v;

if ( ! open(CMD,"$lmstat -c $opt_f |") ) {
  print "$PROGNAME UNKNOWN: ERROR: Could not open \"$lmstat -c $opt_f\" ($!)\n";
  exit exit $ERRORS{'UNKNOWN'};
}

my $serverup = 0;
my @upsrv; 
my @downsrv;  # list of servers up and down

# key off of the term "license server" and
# grab the status.  Keep going until "Vendor" is found
#

#
# Collect list of license servers by their status
# Vendor daemon status is ignored for the moment.

while ( <CMD> ) {
  next if (/^lmstat/);   # ignore 1st line - copyright
  next if (/^Flexible/); # ignore 2nd line - timestamp
  (/^Vendor/) && last;   # ignore Vendor daemon status
  print $_ if $opt_v;
	
  if ($_ =~ /license server /) {	# matched 1 (of possibly 3) license server
    s/^\s*//;				#some servers start at col 1, other have whitespace
					# strip staring whitespace if any
    if ( $_ =~ /UP/) {
      $_ =~ /^(.*):/ ;
      push(@upsrv, $1);
      print "up:$1:\n" if $opt_v;
    } else {
      $_ =~ /^(.*):/; 
      push(@downsrv, $1);
      print "down:$1:\n" if $opt_v;
    }
  }
}

close CMD;

if ($opt_v) {
  print "License Servers running: ".scalar(@upsrv) ."\n";
  foreach my $upserver (@upsrv) {
    print "$upserver\n";
  }
  print "License servers not running: ".scalar(@downsrv)."\n";
  foreach my $downserver (@downsrv) {
    print "$downserver\n";
  }
}

#
# print list of servers which are up.
#
if (scalar(@upsrv) > 0) {
  print "License Servers running:";
  foreach my $upserver (@upsrv) {
    print "$upserver,";
  }
}
#
# Ditto for those which are down.
#
if (scalar(@downsrv) > 0) {
  print "License servers NOT running:";
  foreach my $downserver (@downsrv) {
    print "$downserver,";
  }
}

# perfdata
print "\n|flexlm::up:".scalar(@upsrv).";down:".scalar(@downsrv)."\n";

exit $ERRORS{'OK'} if ( scalar(@downsrv) == 0 );
exit $ERRORS{'WARNING'} if ( (scalar(@upsrv) > 0) && (scalar(@downsrv) > 0));

exit $ERRORS{'CRITICAL'};
