#!/usr/bin/perl -w # script for interfacing with flexLM license manager # to configure set $flexLMCmd # to troubleshoot, set LOGLEVEL (0 - 7, 7 is most verbose) # Note: Due to the inherent conflict with the plus sign ("+"), the provided script # replaces occurrences of the plus sign in license names with the underscore symbol("_"). # This replacement requires that licenses with a plus sign in their names be requested # with an underscore in place of any plus signs. use Time::Local; use Time::localtime; use strict; my $LOGLEVEL = 0; # # Insert lmstat (or lmutil lmstat) command here with -a and -c (license file) # my $flexLMCmd = "SETME"; #my $flexLMCmd= "/full/path/lmutil lmstat -c /full/path/license.dat -a"; my $title = ""; my $config = 0; my $avail = 0; my $sw = ""; my $firstTime = 1; my %swC = (); # sw configured # keys are sw titles my %swA = (); # sw available # keys are sw titles # auto-detect flexLM version/format my $NOT_SET = 0; my $OLD_FORMAT = 1; my $NEW_FORMAT = 2; my $format = $NOT_SET; my $tm = localtime; my $epochTime = timelocal($tm->sec, $tm->min, $tm->hour, $tm->mday, $tm->mon, $tm->year); my $licenseCounter = 0; if ($flexLMCmd =~ "SETME") { if ($LOGLEVEL >= 0) { print "ERROR: script has not been configured, set \$flexLMCmd and retry\n"; } exit(1); } my ($cmd) = split /\s+/, $flexLMCmd; unless( -x $cmd ) { if ($LOGLEVEL >= 0) { print "ERROR: license query command not executable ($flexLMCmd)\n"; } exit(1); } #"$flexLMCmd not executable!"); } open (FLEXLM, "$flexLMCmd |") or die "Unable to execute license query command: $!\n"; if ($LOGLEVEL >= 1) { print "INFO: executing command $flexLMCmd\n"; } while () { chomp($_); if ($_ =~ m/status on \w+ (\d+)\/(\d+)\/(\d+) (\d+):(\d+)/) { # HEADER: load server timestamp # FORMAT: 6/13/2005 12:10 if ($LOGLEVEL >= 1) { print "INFO: license server header parsed\n"; } $epochTime = timelocal(0, $5, $4, $2, $1 - 1, $3); } if (/Error:/) { # ignore error messages if ($LOGLEVEL >= 1) { print "INFO: ignoring error line $_\n"; } next; } if (($format == $NOT_SET) && ($_ =~ m/Users of.+licenses?/)) { if ($_ =~ m/licenses? available/) { $format = $OLD_FORMAT; if ($LOGLEVEL >= 2) { print "INFO: old format line detected\n"; } } elsif ($_ =~ m/licenses? issued/) { $format = $NEW_FORMAT; if ($LOGLEVEL >= 2) { print "INFO: new format line detected\n"; } } else { if ($LOGLEVEL >= 1) { print "ERROR: invalid flexLM format detected\n"; } exit(1); # unrecognized format } } elsif ((($_ =~ m/licenses? available/) && ($format != $OLD_FORMAT)) || (($_ =~ m/licenses? issued/) && ($format != $NEW_FORMAT))) { if ($LOGLEVEL >= 1) { print "ERROR: inconsistent formats in command output\n"; } exit(1); # switching formats not allowed } if ($format == $OLD_FORMAT) { if ($_ =~ m/Users of ([^:]+):.*Total of (\d+) licenses? available/) { # Write out last stats $avail = $config - $licenseCounter; if (($avail >= 0) && ($title ne "")) { $swA{$title} = $avail; } $licenseCounter = 0; $avail = 0; # start new stats $title = $1; # replace "+"s in license name with "_"s $title =~ s/\+/_/g; $config = $2; if ($config < 0) { next; } $swC{$title} = $config; } elsif ($_ =~ m/, start/) { $licenseCounter++; } } elsif ($format == $NEW_FORMAT) { if ($_ =~ m/Users of ([^:]+):.*Total of (\d+) licenses?.*Total of (\d+)/) { $title = $1; # replace "+"s in license name with "_"s $title =~ s/\+/_/g; $config = $2; $avail = $config - $3; if (($config < 0) || ($avail < 0)) { next; } $swC{$title} = $config; $swA{$title} = $avail; } } } if ($format == $OLD_FORMAT) { # generate last stats if ($LOGLEVEL >= 2) { print "INFO: creating termination stats\n"; } $avail = $config - $licenseCounter; if ($avail >= 0) { $swA{$title} = $avail; } $licenseCounter = 0; $avail = 0; } close FLEXLM; if ($LOGLEVEL >= 2) { print "INFO: displaying license status\n"; } print "GLOBAL UPDATETIME=$epochTime STATE=idle"; $firstTime = 1; foreach $sw (sort keys %swA) { if ($firstTime) { $firstTime = 0; print " ARES="; } else { print ","; } print "$sw:$swA{$sw}"; } $firstTime = 1; foreach $sw (sort keys %swC) { if ($firstTime) { $firstTime = 0; print " CRES="; } else { print ","; } print "$sw:$swC{$sw}"; } print "\n"; if ($LOGLEVEL >= 2) { print "INFO: complete\n"; }