"Fossies" - the Fresh Open Source Software Archive

Member "lmon-1.2/control.pl" (19 May 2005, 12949 Bytes) of package /linux/privat/old/lmon-1.2.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Perl source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "control.pl" see the Fossies "Dox" file reference documentation.

    1 #! /usr/bin/perl -T
    2 # control.pl 1.2 for LMon, anders@bsdconsulting.no, 2005-05-19
    3 # External requirements: Config::IniFiles.
    4 #
    5 # Copyright (c) 2005, Anders Nordby <anders@bsdconsulting.no>
    6 # All rights reserved.
    7 # 
    8 # Redistribution and use in source and binary forms, with or without
    9 # modification, are permitted provided that the following conditions are met:
   10 # 
   11 # * Redistributions of source code must retain the above copyright notice, this
   12 # list of conditions and the following disclaimer.
   13 # 
   14 # * Redistributions in binary form must reproduce the above copyright notice,
   15 # this list of conditions and the following disclaimer in the documentation
   16 # and/or other materials provided with the distribution.
   17 # 
   18 # * Neither the name of BSD Consulting nor the names of its contributors may
   19 # be used to endorse or promote products derived from this software without
   20 # specific prior written permission.
   21 # 
   22 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   23 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   25 # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
   26 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   27 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   28 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   29 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   30 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   31 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32 
   33 package LMonControl;
   34 use Config::IniFiles;
   35 use FindBin qw($Bin);
   36 use Getopt::Std;
   37 use POSIX;
   38 use strict;
   39 use IPC::Open3;
   40 
   41 $ENV{PATH} = "/sbin:/bin:/usr/sbin:/usr/bin";
   42 $ENV{ENV} = "";
   43 
   44 $LMonControl::gensect = "general";
   45 $LMonControl::logvar = "log";
   46 $LMonControl::rulevar = "rules";
   47 $LMonControl::namevar = "name";
   48 $LMonControl::modevar = "mode";
   49 $LMonControl::sysnamevar = "sysname";
   50 $LMonControl::buffervar = "buffer";
   51 $LMonControl::fromvar = "from";
   52 $LMonControl::tovar = "to";
   53 $LMonControl::mailserversvar = "mailservers";
   54 $LMonControl::cmdok = '([-\w\.\/\ \"\@\;\_]+)';
   55 $LMonControl::fnok = '([-\w\.\_]+)';
   56 
   57 $LMonControl::commname = "^perl";
   58 $LMonControl::argcheck = "lmon\.pl";
   59 $LMonControl::cfgfile = "$Bin/control.cfg";
   60 $LMonControl::oscheck = '^(SunOS|Linux|FreeBSD)$';
   61 
   62 die("ERROR: Unknown operating system") unless ((POSIX::uname)[0] =~ /$LMonControl::oscheck/);
   63 
   64 use vars qw { $opt_i };
   65 
   66 sub readconfig {
   67     if (! -f $LMonControl::cfgfile) {
   68         die("ERROR: Config file $LMonControl::cfgfile not found");
   69     } elsif (! -T $LMonControl::cfgfile) {
   70         die("ERROR: Config file $LMonControl::cfgfile is not a text file");
   71     } else {
   72         tie %LMonControl::cfg, 'Config::IniFiles', ( -file => $LMonControl::cfgfile );
   73     }
   74 }
   75 
   76 sub usage {
   77     print "Usage: control.pl [options] <keyword>\n\n";
   78     print "\tlist\t\t\tlist configured instances\n";
   79     print "\tstart\t\t\tstart all configured instances\n";
   80     print "\tstart -i <instance>\tstart given instances\n";
   81     print "\tstop\t\t\tstop all configured instances\n";
   82     print "\tstop -i <instance>\tstop given instances\n";
   83     print "\tstatus\t\t\tprint status for all configured instances\n";
   84     print "\tstatus -i <instance>\tprint status for given instance\n";
   85     exit(1);
   86 }
   87 
   88 sub pscmd {
   89     # $_[0]: cmd $_[1]: extra (optional)
   90     my $cmd = $_[0];
   91     my $extracmd = $_[1];
   92     if ($cmd =~ /^$LMonControl::cmdok$/) {
   93         $cmd = $1;
   94         $cmd .= " 2>/dev/null | tail +2";
   95         if ($extracmd) { $cmd .= " " . $extracmd; }
   96         return `$cmd`;
   97     } else {
   98         return "";
   99     }
  100 }
  101 
  102 sub instpid {
  103 # $_[0]: inst
  104     my $inst = $_[0];
  105     my $pidfile = $Bin . "/" . $inst . ".pid";
  106     my $username = getpwuid(getuid);
  107 
  108     if (! -T $pidfile) {
  109         # PID file missing or not a text file
  110         return 0;
  111     } else {
  112         open(PID, $pidfile);
  113         my $regpid = <PID>;
  114         close(PID);
  115         chomp($regpid);
  116         if (!int($regpid)) {
  117             return 0;
  118         } else {
  119             my $psuser;
  120             my $pspid;
  121             my $pscomm;
  122             my $psargs;
  123             for ((POSIX::uname)[0]) {
  124                 /^(FreeBSD|Linux)$/ and do {
  125                     $psuser = pscmd("ps -p $regpid -oruser");
  126                     $psuser =~ s@\s+$@@g;
  127                     $pspid = pscmd("ps -p $regpid -opid");
  128                     $pspid =~ s@\s+$@@g;
  129                     $pscomm = pscmd("ps -c -p $regpid -ocommand");
  130                     $pscomm =~ s@\s+$@@g;
  131                     $psargs = pscmd("ps -ww -p $regpid -ocommand");
  132                     $psargs =~ s@\s+$@@g;
  133                     next;
  134                 };
  135                 /^SunOS$/   and do {
  136                     $psuser = pscmd("ps -p $regpid -oruser", "| awk '{print \$1}'");
  137                     $pspid = pscmd("ps -p $regpid -opid");
  138                     $pscomm = pscmd("ps -p $regpid -ocomm", "| xargs -n 1 basename");
  139                     $psargs = pscmd("ps -p $regpid -oargs");
  140                     next;
  141                 };
  142             }
  143             chomp($psuser);
  144             chomp($pspid);
  145             chomp($pscomm);
  146             chomp($psargs);
  147 
  148             if (int($pspid) && $regpid == $pspid && $psuser eq "$username" && $pscomm =~ /$LMonControl::commname/ && $psargs =~ /$LMonControl::argcheck/) {
  149                 return($regpid);
  150             } else {
  151                 return(0);
  152             }
  153         }
  154     }
  155 }
  156 
  157 sub statusinst {
  158 # $_[0]: instance name
  159     my $inst = $_[0];
  160     my $pid = instpid($inst);
  161     if ($pid) {
  162         print "$inst up, PID $pid.\n";
  163     } else {
  164         print "$inst down.\n";
  165     }
  166 }
  167 
  168 sub startinst {
  169 # $_[0]: instance name
  170     my $inst = $_[0];
  171 
  172     print "Start lmon.pl instance $_[0]: ";
  173     if (!instpid($inst)) {
  174         my $cmd = "cd $Bin; ./lmon.pl -r \"" . $LMonControl::cfg{"$inst"}{"$LMonControl::rulevar"} . "\" -f \"" . $LMonControl::cfg{"$inst"}{"$LMonControl::logvar"} . "\" -p \"" . $inst . ".pid\" -d";
  175 
  176         if (exists $LMonControl::cfg{"$inst"}{"$LMonControl::modevar"}) {
  177             if ($LMonControl::cfg{"$inst"}{"$LMonControl::modevar"} eq "include") {
  178                 $cmd .= " -i";
  179             }
  180         } elsif (exists $LMonControl::cfg{"$LMonControl::gensect"}{"$LMonControl::modevar"} && $LMonControl::cfg{"$LMonControl::gensect"}{"$LMonControl::modevar"} eq "include") {
  181                 $cmd .= " -i";
  182         }
  183 
  184         if (exists $LMonControl::cfg{"$inst"}{"$LMonControl::sysnamevar"}) {
  185                 $cmd .= " -s \"" . $LMonControl::cfg{"$inst"}{"$LMonControl::sysnamevar"} . "\"";
  186         } elsif (exists $LMonControl::cfg{"$LMonControl::gensect"}{"$LMonControl::sysnamevar"}) {
  187                 $cmd .= " -s \"" . $LMonControl::cfg{"$LMonControl::gensect"}{"$LMonControl::sysnamevar"} . "\"";
  188         }
  189 
  190         if (exists $LMonControl::cfg{"$inst"}{"$LMonControl::fromvar"}) {
  191                 $cmd .= " -F \"" . $LMonControl::cfg{"$inst"}{"$LMonControl::fromvar"} . "\"";
  192         } elsif (exists $LMonControl::cfg{"$LMonControl::gensect"}{"$LMonControl::fromvar"}) {
  193                 $cmd .= " -F \"" . $LMonControl::cfg{"$LMonControl::gensect"}{"$LMonControl::fromvar"} . "\"";
  194         }
  195 
  196         if (exists $LMonControl::cfg{"$inst"}{"$LMonControl::tovar"}) {
  197                 $cmd .= " -t \"" . $LMonControl::cfg{"$inst"}{"$LMonControl::tovar"} . "\"";
  198         } elsif (exists $LMonControl::cfg{"$LMonControl::gensect"}{"$LMonControl::tovar"}) {
  199                 $cmd .= " -t \"" . $LMonControl::cfg{"$LMonControl::gensect"}{"$LMonControl::tovar"} . "\"";
  200         }
  201 
  202         if (exists $LMonControl::cfg{"$inst"}{"$LMonControl::mailserversvar"}) {
  203                 $cmd .= " -m \"" . $LMonControl::cfg{"$inst"}{"$LMonControl::mailserversvar"} . "\"";
  204         } elsif (exists $LMonControl::cfg{"$LMonControl::gensect"}{"$LMonControl::mailserversvar"}) {
  205                 $cmd .= " -m \"" . $LMonControl::cfg{"$LMonControl::gensect"}{"$LMonControl::mailserversvar"} . "\"";
  206         }
  207 
  208         if (exists $LMonControl::cfg{"$inst"}{"$LMonControl::buffervar"}) {
  209                 $cmd .= " -b \"" . $LMonControl::cfg{"$inst"}{"$LMonControl::buffervar"} . "\"";
  210         } elsif (exists $LMonControl::cfg{"$LMonControl::gensect"}{"$LMonControl::buffervar"}) {
  211                 $cmd .= " -b \"" . $LMonControl::cfg{"$LMonControl::gensect"}{"$LMonControl::buffervar"} . "\"";
  212         }
  213         if (exists $LMonControl::cfg{"$inst"}{"$LMonControl::namevar"}) {
  214                 $cmd .= " -n \"" . $LMonControl::cfg{"$inst"}{"$LMonControl::namevar"} . "\"";
  215         }
  216 
  217         if (!exists $LMonControl::cfg{"$inst"}{"$LMonControl::logvar"}) {
  218             print "FAIL, instance $inst needs configuration parameter " . $LMonControl::logvar . ".\n";
  219         } elsif (! -f $LMonControl::cfg{"$inst"}{"$LMonControl::logvar"}) {
  220             print "FAIL, log file " . $LMonControl::cfg{"$inst"}{"$LMonControl::logvar"} . " does not exist.\n";
  221         } elsif (! -f $LMonControl::cfg{"$inst"}{"$LMonControl::rulevar"}) {
  222             print "FAIL, rule file " . $LMonControl::cfg{"$inst"}{"$LMonControl::rulevar"} . " does not exist.\n";
  223         } elsif (! -T $LMonControl::cfg{"$inst"}{"$LMonControl::rulevar"}) {
  224             print "FAIL, rule file " . $LMonControl::cfg{"$inst"}{"$LMonControl::rulevar"} . " is not a text file.\n";
  225         } else {
  226 #           print "TRY: $cmd\n";
  227 
  228 # untaint $cmd if characters are OK, sort-of
  229             if ($cmd =~ /^$LMonControl::cmdok$/) {
  230                 $cmd = $1;
  231 
  232                 local(*IN, *OUT, *ERR);
  233                 my $mypid = open3(*IN, *OUT, *ERR, $cmd);
  234                 close(IN);
  235 
  236                 my $errdata;
  237                 while (<ERR>) {
  238                     $errdata .= $_;
  239                 }
  240                 close(ERR);
  241                 close(OUT);
  242                 waitpid($mypid, 0);
  243                 my $ret = $?;
  244 
  245                 if ($ret == 0) {
  246                     print "OK.\n";
  247                 } else {
  248                     print "FAIL, startup problems:\n\n$errdata\n";
  249                 }
  250             } else {
  251                 my $badargs = $cmd;
  252                 $badargs =~ s@$LMonControl::cmdok@@g;
  253                 print "FAIL, invalid argument characters\nin command for instance $inst (see cmdok setting or disable\n-T option for Perl): $badargs.\n";
  254             }
  255         }
  256     } else {
  257         print "FAIL, already running.\n";
  258     }
  259 }
  260 
  261 sub stopinst {
  262 # $_[0]: instance name
  263     my $inst = $_[0];
  264 
  265     print "Stop lmon.pl instance $_[0]: ";
  266     my $pid = instpid($inst);
  267 
  268     if (int($pid)) {
  269         if ($pid =~ /^(\d+)$/) {
  270             # untaint PID
  271             $pid = $1;
  272 
  273             kill 'TERM', $pid;
  274             my $pidfile = $inst . ".pid";
  275             if ($pidfile =~ /^$LMonControl::fnok$/) {
  276                 # Untaint pidfile filename
  277                 $pidfile = $1;
  278                 if (-e $pidfile) { unlink($pidfile) };
  279             }
  280             print "DONE\n";
  281         } else {
  282             print "no valid PID number found.\n";
  283         }
  284     } else {
  285         print "not running.\n";
  286     }
  287 }
  288 
  289 sub fixconfig {
  290     my $inst;
  291     foreach $inst (keys %LMonControl::cfg) {
  292         next if ($inst =~ /^$LMonControl::gensect$/);
  293 
  294         # Fix the rule file filename/path
  295         if (!exists $LMonControl::cfg{"$inst"}{"$LMonControl::rulevar"}) {
  296             # No rule file specified, use default: <instance>.rules in $Bin
  297             $LMonControl::cfg{"$inst"}{"$LMonControl::rulevar"} = $Bin . "/" . $inst . ".rules";
  298         } elsif (! -f $LMonControl::cfg{"$inst"}{"$LMonControl::rulevar"}) {
  299             # Rule file not found, add $Bin before filename
  300             $LMonControl::cfg{"$inst"}{"$LMonControl::rulevar"} = $Bin . "/" . $LMonControl::cfg{"$inst"}{"$LMonControl::rulevar"};
  301         }
  302     }
  303 }
  304 
  305 sub ckpids {
  306     opendir(DIR, $Bin);
  307     my @dirfiles = readdir DIR;
  308     closedir(DIR);
  309     my $dirfile;
  310     foreach $dirfile (@dirfiles) {
  311         next if ($dirfile !~ /\.pid$/);
  312         my $inst = $dirfile;
  313         $inst =~ s@\.pid$@@;
  314         my $pidfile = $Bin . "/" . $dirfile;
  315 
  316         if (! -T $pidfile) {
  317             print "WARNING: PID file $dirfile found in program dir. Not even a valid text file!\n";
  318         } elsif (!exists $LMonControl::cfg{"$inst"}) {
  319             print "WARNING: PID file $dirfile found in program dir, but $inst is not in config.\n";
  320         } else {
  321             my $dirpid = $Bin . "/" . $dirfile;
  322             open(PID, $dirpid);
  323             my $regpid = <PID>;
  324             close(PID);
  325             if (!int($regpid)) {
  326                 print "WARNING: PID file $dirfile found in program dir, but has no number.\n";
  327             } else {
  328                 my $ckpid = instpid($inst);
  329                 if ($ckpid && $ckpid != $regpid) {
  330                     print "WARNING: PID file $dirfile found in program dir, but has unexpected PID.\n";
  331                 }
  332             }
  333         }
  334     }
  335 }
  336 
  337 if ($ARGV[0]) {
  338     if ($ARGV[0] =~ /^(start|stop|status)$/) {
  339 
  340         my $keyword = $ARGV[0];
  341         @ARGV = grep(!/^(start|stop|status)/, @ARGV);
  342         push(@ARGV, $keyword);
  343     }
  344 } else {
  345     usage;
  346 }
  347 
  348 getopts('i:');
  349 my $inst;
  350 
  351 for ($ARGV[0]) {
  352     /^start$/   and do {
  353         readconfig; fixconfig;
  354         if ($opt_i) {
  355             if ($opt_i eq $LMonControl::gensect) {
  356                 print "Could not start invalid instance $opt_i.\n";
  357             } elsif (exists $LMonControl::cfg{"$opt_i"}) {
  358                 startinst($opt_i);
  359             } else {
  360                 print "Could not start instance $opt_i, does not exist in configuration.\n";
  361             }
  362         } else {
  363             foreach $inst (keys %LMonControl::cfg) {
  364                 next if ($inst =~ /^$LMonControl::gensect$/);
  365                 startinst($inst);
  366             }
  367         }
  368         next;
  369     };
  370     /^stop$/    and do {
  371         readconfig;
  372         if ($opt_i) {
  373             if (exists $LMonControl::cfg{"$opt_i"}) {
  374                 stopinst($opt_i);
  375             } else {
  376                 print "Could not stop instance $opt_i, does not exist in configuration.\n";
  377             }
  378         } else {
  379             foreach $inst (keys %LMonControl::cfg) {
  380                 next if ($inst =~ /^$LMonControl::gensect$/);
  381                 stopinst($inst);
  382             }
  383         }
  384         next;
  385     };
  386     /^list$/    and do {
  387         readconfig;
  388         print "Instances:\n\n";
  389         foreach $inst (keys %LMonControl::cfg) {
  390             next if ($inst =~ /^$LMonControl::gensect$/);
  391             print "$inst\n";
  392         }
  393         next;
  394     };
  395     /^status$/  and do {
  396         readconfig;
  397         if ($opt_i) {
  398             if (exists $LMonControl::cfg{"$opt_i"}) {
  399                 statusinst($opt_i);
  400             } else {
  401                 print "Will not check status for instance $opt_i,\ndoes not exist in configuration.\n";
  402             }
  403         } else {
  404             foreach $inst (keys %LMonControl::cfg) {
  405                 next if ($inst =~ /^$LMonControl::gensect$/);
  406                 statusinst($inst);
  407             }
  408             ckpids;
  409         }
  410         ckpids;
  411         next;
  412     };
  413     usage;
  414 }