#!/usr/bin/perl


####################################################################################################
####################################################################################################
# Yaa! start/stop/restart/status facility                                                          #
#                                                                                                  #
# Useful when regularly checking the status of Yaa! daemon e.g. through a cronjob                  #
# Just call "check.pl start" - it checks if Yaa! is already running and only starts it, if it's    #
# not running currently                                                                            #
#                                                                                                  #
# @author Gabriel Schuster <sourcecode@actra.de>                                                   #
# @copyright Copyright 2008, actra.development, Korntal-Muenchingen                                #
#                                                                                                  #
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                      #
#                               NEW BSD LICENSE                                                    #
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                      #
#                                                                                                  #
#                                                                                                  #
# Copyright (c) 2008, actra.development                                                            #
# All rights reserved.                                                                             #
#                                                                                                  #
# Redistribution and use in source and binary forms, with or without                               #
# modification, are permitted provided that the following conditions are met:                      #
#    - Redistributions of source code must retain the above copyright notice,                      #
#      this list of conditions and the following disclaimer.                                       #
#    - 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.                                                                               #
#    - Neither the name of actra.development nor the names of its                                  #
#      contributors may be used to endorse or promote products derived from                        #
#      this software without specific prior written permission.                                    #
#                                                                                                  #
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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.                                                                      #
####################################################################################################
####################################################################################################


####################################################################################################
####################################################################################################
# README:                                                                                          #
#                                                                                                  #
# 1) Install Yaa!                                                                                  #
# 2) Install perl modules: File::Basename, IPC::Open3                                              #
# 3) Specify $yaaDotPL below                                                                       #
# 4) Done.                                                                                         #
#                                                                                                  #
# Quite simple, huh? :)                                                                            #
#                                                                                                  #
# Usage:                                                                                           #
# /path/to/check.pl [((dbg|deb|debug)|short)] [(start|stop|restart)]                               #
#                                                                                                  #
# Options:                                                                                         #
#     debug:   Print to STDOUT what's going on                                                     #
#     short:   Only print short messages to STDOUT                                                 #
#     start:   starts Yaa! if it's not running                                                     #
#     stop:    stops Yaa! if it's running                                                          #
#     restart: restarts Yaa!                                                                       #
#                                                                                                  #
# Yaa! check.pl expects the following directory layout:                                            #
# /path/to/yaa                                                                                     #
#             /bin             ("Binary" files / scripts)                                          #
#                 /yaa.pl      (as specified in $yaaDotPL)                                         #
#                 /check.pl    (THIS script)                                                       #
#             /conf            (Configuration files)                                               #
#                  /yaa.conf   (Your Yaa! configuration file)                                      #
#             /lib             (The library files delivered with Yaa!)                             #
#             /tmp             (Temporary files, would be a good idea to place Yaa!'s yaa.lock,    #
#                               yaa.pid and timeframe-db here)                                     #
####################################################################################################
####################################################################################################


# Specify the name of your Yaa! script file (default: yaa.pl)
my $yaaDotPL = 'yaa.pl';


####################################################################################################
####################################################################################################
#                                                                                                  #
#         DO NOT EDIT ANYTHING BELOW THIS LINE UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING!         #
#                                                                                                  #
####################################################################################################
####################################################################################################


BEGIN {
      if(defined($ENV{'YAA_DEBUG'})) {
            undef $ENV{'YAA_DEBUG'};
            system('unset YAA_DEBUG');
      }
}


use strict;
use warnings;
use Cwd 'abs_path';
use File::Basename;
use IPC::Open3;


my $debug     = (defined $ARGV[0] && $ARGV[0] =~ /^d(eb(ug)?|bg)?$/) || (defined $ARGV[1] && $ARGV[1] =~ /^d(eb(ug)?|bg)?$/) ? 1 : 0;
my $short     = $debug == 0 && ((defined $ARGV[0] && $ARGV[0] eq 'short') || (defined $ARGV[1] && $ARGV[1] eq 'short')) ? 1 : 0;
my $command   = defined $ARGV[0] && $ARGV[0] =~ /^(start|stop|restart|status)$/ ? $ARGV[0] : undef;
   $command   = !defined $command && defined $ARGV[1] && $ARGV[1] =~ /^(start|stop|restart|status)$/ ? $ARGV[1] : $command;

if(!defined $command || !length($command)) {
      print 'Usage: '.$0." [((dbg|deb|debug)|short)] [(start|stop|restart)]\n";
      exit 0;
}

my $dirname   = dirname(abs_path($0));
my $configDir = dirname($dirname).'/conf';
my $yaaScript = $dirname.'/'.$yaaDotPL;

chdir($dirname);
$ENV{'PATH'} = $dirname.':'.$ENV{'PATH'};

my $stateCMD = $yaaScript.' --action=status';
my $stopCMD  = $yaaScript.' --action=stop >/dev/null 2>/dev/null';
my $startCMD = $yaaScript.' --action=start --config-file='.$configDir.'/yaa.conf >/dev/null 2>/dev/null';

if(defined($ENV{'YAA_DEBUG'})) {
      die('env: '.$ENV{'YAA_DEBUG'});
}

my($writer, $reader, $error);
my $pid = open3($writer, $reader, $error, $stateCMD);
my $currentState = '';
while(<$reader>) {
      $currentState .= $_;
}

if(length($currentState)) {
      if(defined $command && $command eq 'status') {
            my $status    = length($currentState) && $currentState =~ /^Running as pid/mi ? 'running' : 'not running';
            print 'Status: '.$status."\n";
            
            exit 0;
      }

      if($currentState =~ /^Running as pid/mi) {
            # Yaa! is running
            print "Yaa! is running...\n" if($debug);

            if(defined $command && $command eq 'restart') {
                  print "Restarting Yaa!...\n" if($debug);
                  
                  $pid = open3($writer, $reader, $error, $stopCMD);
                  my $stopResult = <$reader>;
                  print "...stopped\n" if($debug);
                  
                  system('/usr/bin/perl '.$startCMD);
                  print "...started\n" if($debug);
            }
            elsif(defined $command && $command eq 'stop') {
                  print "Stopping Yaa!...\n" if($debug);
                  
                  $pid = open3($writer, $reader, $error, $stopCMD);
                  my $stopResult = <$reader>;
            }
            else {
                  if($debug) {
                       print "Yaa! is already running!\n";

                       exit 0;
                  }
                  elsif($short) {
                       print "already running.\n";

                       exit 0;
                  }
            }
      }
      else {
            # Yaa! is not running
            print "Yaa! seems to be not running...\n" if($debug);

            if(defined $command && $command eq 'start') {
                  print "Starting Yaa!...\n" if($debug);
                  
                  system('/usr/bin/perl '.$startCMD);
                  print "...started\n" if($debug);
            }
            elsif(defined $command && $command eq 'restart') {
                  print "Restarting Yaa!...\n" if($debug);
                  
                  if($currentState !~ /^Process is not running/mi) {
                        $pid = open3($writer, $reader, $error, $stopCMD);
                        my $stopResult = <$reader>;
                        print "...stopped\n" if($debug);
                  }
                  
                  system('/usr/bin/perl '.$startCMD);
                  print "...started\n" if($debug);
            }
            else {
                  if($debug) {
                       print "Yaa! is not running!\n";
                       
                       exit 0;
                  }
                  elsif($short) {
                       print "not running.\n";

                       exit 0;
                  }
            }
      }
      
      if($debug || $short) {
            $pid = open3($writer, $reader, $error, $stateCMD);
            $currentState = '';
            while(<$reader>) {
                  $currentState .= $_;
            }
            
            my $status = length($currentState) && $currentState =~ /^Running as pid/mi ? 'running' : 'not running';
            print 'Status: '.$status."\n" if($debug);
            print ($command =~ /^(re)?start$/ ? ($status eq 'running' ? $command."ed.\n" : "failed.\n") : ($status eq 'running' ? "failed.\n" : "stopped.\n")) if($short);
      }
}
else {
      print "Can not get Yaa! status - please check your setup, especially rights and uid/gid.\n";
      
      exit 1;
}

exit 0;
