#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2003,2007 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)09   1.11   src/csm/samples/sbin/sprc.perl, setup, csm_rfish, rfishs001b 11/1/05 22:03:42

#
#   Module:	Simple Platform-independent Resource Controller (SPRC)
#
#
#   Purpose:	The purpose of this script is to supply a simple platform independent
#              	interface to system daemons.  These are often refered to as resources.
#
#               sprc  provides users with an common command line interface that can handle
#               typical resource managment tasks on both AIX and Linux cluser nodes.
#
#               When used with CFM, sprc simplifies managing daemons across a hetrogenous
#		cluster.
#
#
#  Source:	/opt/csm/samples/sbin/sprc.perl
#
#  Installed:	/opt/csm/bin/sprc
#
#
#
#  Exceptions:	This tool supports exceptions to the variety of names found with known
#		resources.  sprc has the reponsibility for resolving the name correctly
#		for a given platform ( see aixExceptionHandler for example- and yes it is
#		a hack )
#
#		If you add an exception to this tool,  please update the list.
#
#		.  autofs	= automountd
#		.  ntpd		= xntpd
#

#--------------------------------------------------------------------------------

=head1    sprc.perl

        Development notes:

        The html view of the pod headers in this file can be updated
        by running the command:

                  pod sprc.perl

        The html veiw of the pod headers will be in the file sprc.perl.html

=cut

#--------------------------------------------------------------------------------

=head3	use staements


=cut

#--------------------------------------------------------------------------------

use strict;

#use lib $::csmpm;
use FindBin qw($Bin);
use lib "$Bin";
use Getopt::Long;

#--------------------------------------------------------------------------------

=head3  file scope data

=cut

#--------------------------------------------------------------------------------

# remote shell vairables
my $aix_rsh;
my $linux_ssh;

my $AIX_AUTOFS_CMD = "/usr/sbin/automount";

#--------------------------------------------------------------------------------

=head3  messages

=cut

#--------------------------------------------------------------------------------

my $EMsgAIXOnly    = "the -g flag is only appropriate for AIX hosts. \n";
my $EMsgNoResource =
  "sprc:  need a  resource for this command - try:  sprc --help \n";
my $EMsgUnsupporteOS = "sprc:  unsupported Operating System \n";
my $IMsgNoParameters =
  "sprc:  parmeters needed for this command - try:  sprc --help\n";
my $IMsgUsage =
  "Usage: sprc [[-h?vV]|{[--cycle|-c]|[--kill|-k]|[--list|-l]|[--start|-s]|[--stop]}][[--remote|-r]{name|ipaddr}]{res|-g group}\n";

#--------------------------------------------------------------------------------

=head3  sub usage

=cut

#--------------------------------------------------------------------------------

sub usage ()
{
	print $IMsgUsage;
	exit;
}

#--------------------------------------------------------------------------------

=head3  sub help

=cut

#--------------------------------------------------------------------------------

sub help()
{

	print "\n";
	print
	  "--------------------------------------------------------------------------------\n";
	print "\n";
	print "sprc:   simple platform independent resource controller\n";

	print "\n";
	print $IMsgUsage;
	print "\n";

	print "Options: \n";
	print "    -c | --cycle         - kill and restart a running resource.\n";
	print
	  "    -g                   - apply operation to a resource group (AIX only)\n";
	print "    -h | ?               - print short usage message. \n";
	print "    --help               - print this help message. \n";
	print "    -k | --kill          - stop a resource (same as --stop). \n";
	print "    -l | --list          - list the status of a resource. \n";
	print "    -r | --remote        - execute operation on a remote host.\n";
	print "    -s | --start         - start a resource. \n";
	print "    --stop               - stop a resource (same as -k,--kill). \n";
	print "    -v | -V              - verbose output. \n";

	print "\n";
	print "Examples: \n";

	print "\n";
	print "    Kill and start a running instance of ntpd on the local host. \n";

	print "\n";
	print "        sprc -c ntpd \n";

	print "\n";
	print "    Kill and start ntpd on the remote host, validHostName. \n";

	print "\n";
	print "        sprc --cycle --remote validHostName ntpd \n";

	print "\n";

	exit;
}

#--------------------------------------------------------------------------------

=head3  sub getArgs

=cut

#--------------------------------------------------------------------------------

sub getArgs
{

	# Checks case in GetOptions
	$Getopt::Long::ignorecase = 0;

	# Allows opts to be grouped (e.g. -avx)
	Getopt::Long::Configure("bundling");

	if (!@ARGV) { print $IMsgNoParameters; exit; }
	GetOptions(
			   'c'      => \$::CYCLE,
			   'cycle'  => \$::CYCLE,
			   'h|?'    => \$::USAGE,
			   'g'      => \$::GROUP,
			   'group'  => \$::GROUP,
			   'help'   => \$::HELP,
			   'k'      => \$::KILL,
			   'kill'   => \$::KILL,
			   'l'      => \$::LIST,
			   'list'   => \$::LIST,
			   'r'      => \$::RHOST,
			   'remote' => \$::RHOST,
			   's'      => \$::START,
			   'start'  => \$::START,
			   'stop'   => \$::KILL,
			   'v'      => \$::VERBOSE,
			   'V'      => \$::VERBOSE,
			  );

	if ($::USAGE) { print $IMsgUsage; }
	if ($::HELP)  { &help(); }
	if ($::RHOST) { $aix_rsh = " rsh "; $linux_ssh = " ssh "; }
}

#--------------------------------------------------------------------------------

=head3  sub getPlatform

	Returns a testable OS Platform string.

=cut

#--------------------------------------------------------------------------------

sub getPlatform
{

	my $platform = qx ' uname -s ';
	chomp($platform);

	if ($platform eq "AIX") { return "AIX"; }

	elsif ($platform eq "Linux")
	{
		if (-f "/etc/redhat-release") { return "Redhat"; }

		elsif (-f "/etc/SuSE-release")
		{
			if (!system("grep SLES-7 /etc/SuSE-release "))
			{
				return "SLES-7";
			}
			elsif (   !system("grep SLES- /etc/SuSE-release ")
				   || !system("grep -i 'SuSE Linux' /etc/SuSE-release"))
			{
				return "Not_SLES-7";    # SLES but not SLES-7
			}
		}
	}
	else                                # error, unsupported platform
	{
		print " $EMsgUnsupporteOS \n";
		exit;
	}
}

#--------------------------------------------------------------------------------

=head3  sub aixExceptionHandler - put special daemon-specific hacks here

=cut

#--------------------------------------------------------------------------------

sub aixExceptionHandler
{

	my ($resource) = @_;

	# switch on $resource

	if ($resource eq "autofs")
	{
		if ($::GROUP) { return "autofs"; }

		return "automountd";
	}

	if ($resource eq "automount")
	{
		if ($::GROUP) { return "autofs"; }

		return "automountd";
	}

	if ($resource eq "automountd")
	{
		if ($::GROUP) { return "autofs"; }

		return "automountd";
	}

	if ($resource eq "ntpd") { return "xntpd"; }

	return $resource;

}

#--------------------------------------------------------------------------------

=head3  sub redhatExceptionHandler - put special daemon-specific hack here.

=cut

#--------------------------------------------------------------------------------

sub redhatExceptionHandler
{

	my ($resource) = @_;

	# switch on $resource

	if ($resource eq "automountd") { return "autofs"; }

	if ($resource eq "xntpd") { return "ntpd"; }

	return $resource;

}

#--------------------------------------------------------------------------------

=head3  sub sles7ExceptionHandler - put special daemon-specific hacks here

=cut

#--------------------------------------------------------------------------------

sub sles7ExceptionHandler
{

	my ($resource) = @_;

	# switch on $resource

	if ($resource eq "automountd") { return "autofs"; }

	if ($resource eq "ntpd") { return "xntpd"; }

	return $resource;

}

#--------------------------------------------------------------------------------

=head3  sub notSles7ExceptionHandler - put special daemon-specific hacks here

=cut

#--------------------------------------------------------------------------------

sub notSles7ExceptionHandler
{

	my ($resource) = @_;

	# switch on $resource

	if ($resource eq "automountd") { return "autofs"; }

	if ($resource eq "ntpd") { return "xntpd"; }

	return $resource;

}

#--------------------------------------------------------------------------------

=head3  sub aixRsourceHandler

        Handles AIX Unix resource requirements

        Notes:

=cut

#--------------------------------------------------------------------------------

sub aixResourceHandler
{
	my $scope;
	my ($resource, $host) = @_;

	# $scope is either -s or -g
	if ($::GROUP) { $scope = " -g "; }
	else { $scope = " -s "; }

	if ($::CYCLE)
	{

		# recycle the daemon
		system("$aix_rsh $host stopsrc  $scope $resource ");
		system("$aix_rsh $host startsrc $scope $resource ");

		# start the autofs subsystem
		system($AIX_AUTOFS_CMD );
	}
	if ($::KILL)
	{
		system("$aix_rsh $host stopsrc $scope $resource ");
	}
	if ($::LIST)
	{
		system("$aix_rsh $host lssrc $scope $resource ");
	}
	if ($::START)
	{

		# start the daemon
		system("$aix_rsh $host startsrc $scope $resource ");

		# start the autofs subsystem
		system($AIX_AUTOFS_CMD );
	}
}

#--------------------------------------------------------------------------------

=head3  sub redhatResourceHandler

        Handles Redhat Linux resource requirements

        Notes:

=cut

#--------------------------------------------------------------------------------

sub redhatResourceHandler
{
	my ($resource, $host) = @_;

	#  set absolute path to linux resource ( in init.d )
	my $abs_resource = "/etc/init.d/$resource";

	if ($::CYCLE)
	{
		system("$linux_ssh $host  $abs_resource stop ");
		system("$linux_ssh $host $abs_resource start ");
	}
	if ($::KILL)
	{
		system("$linux_ssh $host $abs_resource stop ");
	}
	if ($::LIST)
	{
		system("$linux_ssh $host $abs_resource status ");
	}
	if ($::START)
	{
		system("$linux_ssh $host $abs_resource start ");
	}
}

#--------------------------------------------------------------------------------

=head3  sub sles7ResourceHandler

        Handles SuSE 7 Linux resource requirements

        Notes:

=cut

#--------------------------------------------------------------------------------

sub sles7ResourceHandler
{

	my ($resource, $host) = @_;

	#  set absolute path to linux resource ( in init.d )
	my $abs_resource = "/etc/init.d/$resource";

	if ($::CYCLE)
	{
		system("$linux_ssh $host  $abs_resource stop ");
		system("$linux_ssh $host $abs_resource start ");
	}
	if ($::KILL)
	{
		system("$linux_ssh $host $abs_resource stop ");
	}
	if ($::LIST)
	{
		system("$linux_ssh $host $abs_resource status ");
	}
	if ($::START)
	{
		system("$linux_ssh $host $abs_resource start ");
	}
}

#--------------------------------------------------------------------------------

=head3  sub notSles7ResourceHandler

        Handles SuSE 8 Linux resource requirements

        Notes:

=cut

#--------------------------------------------------------------------------------

sub notSles7ResourceHandler
{

	my ($resource, $host) = @_;

	#  set absolute path to linux resource ( in init.d )
	my $abs_resource = "/etc/init.d/$resource";

	if ($::CYCLE)
	{
		system("$linux_ssh $host  $abs_resource stop ");
		system("$linux_ssh $host $abs_resource start ");
	}
	if ($::KILL)
	{
		system("$linux_ssh $host $abs_resource stop ");
	}
	if ($::LIST)
	{
		system("$linux_ssh $host $abs_resource status ");
	}
	if ($::START)
	{
		system("$linux_ssh $host $abs_resource start ");
	}
}

#--------------------------------------------------------------------------------

=head3  Main MAIN main

	process comand line then switch on $platform.

=cut

#--------------------------------------------------------------------------------

{    #  main block - controls scope of data

	# values from cmd line
	my $resource;
	my $host;

	# get arguments
	&getArgs();

	# get $platform
	my $platform = &getPlatform();
	if ($platform == -1) { exit; }

	# get the hostname if remote shell flag is set
	if ($::RHOST) { $host = shift @::ARGV; }

	# get resource
	if (@::ARGV) { $resource = shift @::ARGV; }
	else { print $EMsgNoResource; }

	#  handle AIX only condition
	if ($::GROUP && $platform != "AIX") { print $EMsgAIXOnly; exit; }

	# switch on $platform
	{
		if ($platform eq "AIX")
		{
			$resource = &aixExceptionHandler($resource);
			&aixResourceHandler($resource, $host);
		}
		elsif ($platform eq "Redhat")
		{
			$resource = &redhatExceptionHandler($resource);
			&redhatResourceHandler($resource);
		}
		elsif ($platform eq "SLES-7")
		{
			$resource = &sles7ExceptionHandler($resource);
			&sles7ResourceHandler($resource);
		}
		elsif ($platform eq "Not_SLES-7")
		{
			$resource = &notSles7ExceptionHandler($resource);
			&notSles7ResourceHandler($resource);
		}
	}
}
