#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2004,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 
#####################################################################
#                                                                   #
# Module: lsrhws.perl                                               #
#                                                                   #
# Description: Lists (or displays) the attribute values for a       #
#              Cluster Hardware Server resource or resource class.  #
#                                                                   #
#####################################################################
#"@(#)59   1.14   src/csm/hw/svr/cmds/lsrhws.perl, csm.hardware, csm_rfish, rfishs001b 7/4/05 00:52:19"
#

#------------------------------------------------------------------------#
# writes trace information to /var/log/csm/lsrhws.log                    #
#------------------------------------------------------------------------#
sub dprint
{

	if (defined($::opt_v))
	{
		my ($msg) = @_;
		($sec, $min, $hour, $yday) = (localtime)[0, 1, 2, 7];
		$timestamp = sprintf("%02d:%02d:%02d", $hour, $min, $sec);

		my $s = $timestamp . " " . $msg;
		print $::LOG_FILE_HANDLE $s;
	}
}

#-------------------------------------------------------------------------#
# subroutine to print usage statement                                     #
#-------------------------------------------------------------------------#
sub usage
{

	$::MSGSET = 'hwsvrcmd';
	MessageUtils->message('I', 'IMsglsrhwsUsage');
	exit(scalar(@_) ? $_[0] : 1);
}

#-------------------------------------------------------------------------#
# parse_args - Parse the command line for options and operands.           #
#-------------------------------------------------------------------------#
sub parse_args
{

	# process command-line flags
	#
	if (!getopts('hvltdD:s:Lefma:')) { usage(3); }

	if ($::opt_h) { usage(0); }

	# Check for invalid argument.
	#
	if ($ARGV[0] ne "")
	{
		MessageUtils->message('E', 'EMsgInvalidArgument', $ARGV[0]);
		usage(4);
	}

	# Check for switch "-" with no option
	#
	if ($ARGV[0] =~ /^-$/)
	{
		MessageUtils->message('E', 'EMsgMissingOption');
		usage(3);
	}

	# Don't allow -l with other delimiter flags
	#
	if (defined($::opt_l)
		&& (defined($::opt_t) || defined($::opt_d) || defined($::opt_D)))
	{
		MessageUtils->message('E', 'EMsgConflictingArgs', '-l');
		if (defined($::opt_l))
		{
			MessageUtils->message('E', 'EMsgConflictingArgs', '-t');
		}
		if (defined($::opt_d))
		{
			MessageUtils->message('E', 'EMsgConflictingArgs', '-d');
		}
		if (defined($::opt_D))
		{
			MessageUtils->message('E', 'EMsgConflictingArgs', '-D');
		}
		usage(3);
	}

	# Don't allow -t with other delimiter flags
	#
	if (defined($::opt_t)
		&& (defined($::opt_l) || defined($::opt_d) || defined($::opt_D)))
	{
		MessageUtils->message('E', 'EMsgConflictingArgs', '-t');
		if (defined($::opt_l))
		{
			MessageUtils->message('E', 'EMsgConflictingArgs', '-l');
		}
		if (defined($::opt_d))
		{
			MessageUtils->message('E', 'EMsgConflictingArgs', '-d');
		}
		if (defined($::opt_D))
		{
			MessageUtils->message('E', 'EMsgConflictingArgs', '-D');
		}
		usage(3);
	}

	# Don't allow -d with other delimiter flags
	#
	if (defined($::opt_d)
		&& (defined($::opt_l) || defined($::opt_t) || defined($::opt_D)))
	{
		MessageUtils->message('E', 'EMsgConflictingArgs', '-d');
		if (defined($::opt_l))
		{
			MessageUtils->message('E', 'EMsgConflictingArgs', '-l');
		}
		if (defined($::opt_t))
		{
			MessageUtils->message('E', 'EMsgConflictingArgs', '-t');
		}
		if (defined($::opt_D))
		{
			MessageUtils->message('E', 'EMsgConflictingArgs', '-D');
		}
		usage(3);
	}

	# Don't allow -D with other delimiter flags
	#
	if (defined($::opt_D)
		&& (defined($::opt_l) || defined($::opt_d) || defined($::opt_t)))
	{
		MessageUtils->message('E', 'EMsgConflictingArgs', '-D');
		if (defined($::opt_l))
		{
			MessageUtils->message('E', 'EMsgConflictingArgs', '-l');
		}
		if (defined($::opt_d))
		{
			MessageUtils->message('E', 'EMsgConflictingArgs', '-d');
		}
		if (defined($::opt_t))
		{
			MessageUtils->message('E', 'EMsgConflictingArgs', '-t');
		}
		usage(3);
	}

	# Don't allow -L without -s flag.
	#
	if (defined($::opt_L) && !($::opt_s))
	{
		MessageUtils->message('E', 'EMsgConflictingArgs', '-L');
		usage(3);
	}

	# Don't allow -e with other resource class flags
	#
	if (defined($::opt_e)
		&& (defined($::opt_f) || defined($::opt_m))
	   )    # || defined( $::opt_o ) ) )
	{
		MessageUtils->message('E', 'EMsgConflictingArgs', '-e');
		if (defined($::opt_f))
		{
			MessageUtils->message('E', 'EMsgConflictingArgs', '-f');
		}
		if (defined($::opt_m))
		{
			MessageUtils->message('E', 'EMsgConflictingArgs', '-m');
		}

		#        if( defined( $::opt_o ) ) {
		#            MessageUtils->message('E', 'EMsgConflictingArgs', '-o' );
		#        }
		usage(3);
	}

	# Don't allow -f with other resource class flags
	#
	if (defined($::opt_f)
		&& (defined($::opt_e) || defined($::opt_m))
	   )    # || defined( $::opt_o ) ) )
	{
		MessageUtils->message('E', 'EMsgConflictingArgs', '-f');
		if (defined($::opt_e))
		{
			MessageUtils->message('E', 'EMsgConflictingArgs', '-e');
		}
		if (defined($::opt_m))
		{
			MessageUtils->message('E', 'EMsgConflictingArgs', '-m');
		}

		#        if( defined( $::opt_o ) ) {
		#            MessageUtils->message('E', 'EMsgConflictingArgs', '-o' );
		#        }
		usage(3);
	}

	# Don't allow -m with other resource class flags
	#
	if (defined($::opt_m)
		&& (defined($::opt_f) || defined($::opt_e))) #|| defined( $::opt_o ) ) )
	{
		MessageUtils->message('E', 'EMsgConflictingArgs', '-m');
		if (defined($::opt_f))
		{
			MessageUtils->message('E', 'EMsgConflictingArgs', '-f');
		}
		if (defined($::opt_e))
		{
			MessageUtils->message('E', 'EMsgConflictingArgs', '-e');
		}

		#        if( defined( $::opt_o ) ) {
		#            MessageUtils->message('E', 'EMsgConflictingArgs', '-o' );
		#        }
		usage(3);
	}

	# Don't allow -o with other resource class flags
	#
	#    if ( defined( $::opt_o ) &&
	#       ( defined( $::opt_f ) || defined( $::opt_m ) || defined( $::opt_e ) ) )
	#       {
	#        MessageUtils->message('E', 'EMsgConflictingArgs', '-o' );
	#        if( defined( $::opt_f ) ) {
	#            MessageUtils->message('E', 'EMsgConflictingArgs', '-f' );
	#        }
	#        if( defined( $::opt_m ) ) {
	#            MessageUtils->message('E', 'EMsgConflictingArgs', '-m' );
	#        }
	#        if( defined( $::opt_e ) ) {
	#            MessageUtils->message('E', 'EMsgConflictingArgs', '-e' );
	#        }
	#        usage(3);
	#    }
}

#------------------------------------------------------------------------#
# Build Command - builds command to call lsrsrc as an argument           #
#------------------------------------------------------------------------#
sub build_cmd
{

	@::rscs = ("IBM.hw_element", "IBM.hw_frame", "IBM.hw_manager");

	$::div = "--------------------------------";
	my @attrList;
	@::validRHList = ();
	$::errorCaught = 0;
	my $cmd           = "";
	my $command       = "lsrsrc";
	my $pdomainSel    = "ActivePeerDomain==\"ClusterPeerDomain\"";
	my $resourceClass = "";
	my $delimiter     = "\n";
	my $flagv         = "";
	my $flagd         = "";
	my $flaga         = "";
	my $linkClass     = "";
	my $queryAttr     = "";
	my $qClass        = "";
	my $aClass        = "";
	my $rv            = "";
	my $nullHandle    =
	  "0x0000 0x0000 0x00000000 0x00000000 0x00000000 0x00000000";
	my $eleLinkAttr    = "ResourceHandle Element_FrameRH";
	my $frameBlinkAttr = "ResourceHandle";                   # Frame_BPA_MTMS";
	my $frameLinkAttr    = "ResourceHandle Frame_ManagerRH_A Frame_ManagerRH_B";
	my $frameAllLinkAttr = "ResourceHandle Frame_ManagerRH_A Frame_ManagerRH_B";

	dprint("In build_cmd()\n");

	# Populate the lists of attributes using output from the lsrsrcdef cmd.
	#
	dprint("build_cmd: Calling get_attributes() for $::rscs[0]\n");
	@::elementAttr = get_attributes($::rscs[0]);
	dprint("build_cmd: Calling get_attributes() for $::rscs[1]\n");
	@::frameAttr = get_attributes($::rscs[1]);
	dprint("build_cmd: Calling get_attributes() for $::rscs[2]\n");
	@::managerAttr = get_attributes($::rscs[2]);
	dprint("build_cmd: Got attributes for all classes.\n");

	# If no flag, no arguments.  Display all resource classes.
	#
	if (   !defined($::opt_h)
		&& !defined($::opt_e)
		&& !defined($::opt_f)
		&& !defined($::opt_m)
		&& !($::opt_s)
		&& !($::opt_a))
	{
		dprint(   "build_cmd: No flag and no arguments, displaying resource class names.\n"
		);
		if (defined($::opt_t)) { $delimiter = "\t"; }
		if (defined($::opt_d)) { $delimiter = ':'; }
		if ($::opt_D)          { $delimiter = $::opt_D }

		print("\"" . @rscs[0] . "\"");
		shift(@rscs);
		foreach my $cls (@rscs) { print($delimiter. "\"" . $cls . "\""); }
		print("\n");
		return 0;
	}

	# Check value of -v flag.
	#
	if ($::opt_v) { $flagv = " -V"; }

	# Assign delimiter according to flag specified.
	# Default and -l flag is long format.
	#
	if    (defined($::opt_t)) { $flagd = (" -t"); }
	elsif (defined($::opt_d)) { $flagd = (" -d"); }
	elsif ($::opt_D)          { $flagd = (" -D " . $::opt_D); }
	elsif ($::opt_l)          { $flagd = (" -l"); }
	if ($flagd ne "") {
		dprint("build_cmd: $flagd specified for delimiter.\n");
	}

	# Check value of -s flag.
	#
	if ($::opt_s)
	{
		$flags = (" -s '$pdomainSel && ($::opt_s)'");
		dprint("build_cmd: Select string is $::pt_s\n");
	}
	else
	{
		$flags = " -s '$pdomainSel'";
	}

	# Check for resource class.  First check for e|f|m|o flags.
	# If none of the flags are specified, check for s flag and decide
	# based on select string, if s flag not specified, check for a flag
	# and decide based on attribute specified.
	#
	if (defined($::opt_e))
	{
		dprint("build_cmd: -e specified\n");
		$resourceClass = $::rscs[0];
	}
	elsif (defined($::opt_f))
	{
		dprint("build_cmd: -f specified\n");
		$resourceClass = $::rscs[1];
	}
	elsif ($::opt_m)
	{
		dprint("build_cmd: -m specified\n");
		$resourceClass = $::rscs[2];
	}

	#    elsif ($::opt_o)          { $resourceClass = $::rscs[3]; }
	elsif ($::opt_s)
	{
		dprint(   "build_cmd: Calling get_class to determine class for selectstr $::opt_s\n"
		);
		$resourceClass = get_class($::opt_s);
		if ($resourceClass eq "")
		{
			dprint("build_cmd: Invalid selectstr detected $::opt_s\n");
			$::MSGSET = 'hwsvrcmd';
			MessageUtils->message('E', 'EMsgInvalidSelectstr', $::opt_s);
			return 6;
		}
		dprint("Class is $resourceClass\n");
	}
	elsif ($::opt_a) #If all else fails, attempt to get class with first attrib.
	{
		dprint(   "build_cmd: Attempting to determine class from attribute $::opt_a\n"
		);
		$resourceClass = get_class($::opt_a);
		if ($resourceClass eq "")
		{
			dprint("build_cmd: Invalid attribute detected $::opt_a\n");
			$::opt_a =~ s/,/ /g;
			$::MSGSET = 'hwsvrcmd';
			MessageUtils->message('E', 'EMsgInvalidAttr', $::opt_a);
			return 4;
		}
		dprint("Class is $resourceClass\n");
	}

	# Check for attributes.
	#
	if ($::opt_a)
	{
		dprint(
			"build_cmd: Attribute $::opt_a specified, checking for validity\n");

		#Check for invalid attribute and class mismatch.
		#
		my $optA = $::opt_a;
		@::aList = split(/,/, $optA);

		foreach my $attr (@aList)
		{
			$attr =~ s/=.*//;
			dprint("build_cmd: Calling get_class for attribute $attr\n");
			my $class = get_class($attr);
			if ($class eq "")
			{
				dprint("build_cmd: Invalid attribute detected $attr\n");
				$::MSGSET = 'hwsvrcmd';
				MessageUtils->message('E', 'EMsgInvalidAttr', $attr);
				return 4;
			}

			#Check for class mismatch
			if (!defined($::opt_L))
			{
				if (($class ne $resourceClass))
				{
					dprint(            "build_cmd: Invalid attribute for class detected, resourceClass is $resourceClass, attribute class is $class\n"
					);
					$::MSGSET = 'hwsvrcmd';
					MessageUtils->message('E', 'EMsgAttrClassMisMatch', $attr,
									   $resourceClass);
					return 4;
				}
			}
		}

		$aClass = get_class($::opt_a);
		$::opt_a =~ s/,/ /g;
		$flaga = (" " . $::opt_a);
	}

	# Check for -L option.  Get resource handle of the links and
	# display each linked resource grouped by the individual
	# resource specified in the query.
	#
	if (defined($::opt_L))
	{

		dprint("-L SPECIFIED, IN ROUTINE TO GET LINKS\n");
		dprint("build_cmd: -L specified, resourceClass is $resourceClass\n");

		#Determine which link attributes to query based on resource class.
		#
		if ($resourceClass eq $::rscs[0])
		{
			$queryAttr = $eleLinkAttr;
			$linkClass = $::rscs[1];
		}
		elsif ($resourceClass eq $::rscs[1])
		{
			if ($aClass eq $::rscs[0])
			{
				$queryAttr = $frameBlinkAttr;
				$linkClass = $::rscs[0];
			}
			elsif ($aClass eq $::rscs[2])
			{
				$queryAttr = $frameLinkAttr;
				$linkClass = $::rscs[2];
			}
			else    #Let lsrsrc do error checking
			{
				$queryAttr = $frameAllLinkAttr;
				$linkClass = $::rscs[2];
			}
		}
		else
		{
			dprint("build_cmd: No links for $resourceClass\n");
			$::MSGSET = 'hwsvrcmd';
			MessageUtils->message('E', 'EMsgNoLinkFromClass', $resourceClass);
			return 5;
		}
		dprint("build_cmd: Potentially linked class is $linkClass\n");
		dprint("Attributes to query are $queryAttr\n");

		#Check for class mismatch
		#
		foreach my $attr (@aList)
		{
			dprint(      "build_cmd: Calling get_class and determining if $attr is valid for linked class $linkClass\n"
			);
			my $class = get_class($attr);
			if (($class ne $linkClass))
			{
				dprint(         "build_cmd: Invalid attribute $attr for link Class $linkClass\n"
				);
				$attr =~ s/=.*//;
				$::MSGSET = 'hwsvrcmd';
				MessageUtils->message('E', 'EMsgAttrClassMisMatch', $attr,
								   $linkClass);
				return 4;
			}
			dprint("Attribute class is $class\n");
		}

		#Get class instances matching selectstr
		#
		$cmd = "$command -x $flags $resourceClass $queryAttr";
		dprint("QUERYING RESOURCES THAT MATCH THE SELECT STRING\n");
		dprint(   "build_cmd: Calling run_cmd to get class instances matching selectstr $::opt_s\n"
		);
		dprint("cmd is $cmd\n");
		$::resourceHandle = run_command($cmd, 0, 0);
		if (@$::resourceHandle == 0)
		{
			dprint("build_cmd: No matching resources were found.\n");
			$::MSGSET = 'hwsvrcmd';
			MessageUtils->message('I', 'IMsgNoMatchingResource');
			return 6;
		}

		# Go through array containing handles to the linked resources.
		# For each link handle, get and display linked resource instance.
		# First output the resource matching the initial select string,
		# then print the linked resources.
		#
		dprint("STEPPING THROUGH MATCHING RESOURCES\n");
		dprint("build_cmd: Iterating through resource handle array\n");
		my $init   = 0;
		my $header = "";
		my $err;
		foreach my $res (@$::resourceHandle)
		{
			dprint(
				"build_cmd: Current resource handle array element is:\n$res\n");
			$err = $res;
			$err =~ s/^.*: //;
			$err = trim_whitespace($err);

			if (($err =~ /^[0-9]{4}-[0-9]{3}.*/))
			{    # Caught an error
				dprint("build_cmd: Caught error: $res\n");
				$::errorCaught = 1;
				print($err. "\n");
			}
			elsif (($res =~ /resource [0-9]+/)) { }
			elsif ($res =~ /$nullHandle/) { }    #Do nothing.
			else                                 # This is a resource Handle
			{
				$res = trim_whitespace($res);

				#                $res =~ (s/\"/\'/g);
				if ($res =~ /ResourceHandle/)
				{
					dprint("PRINTING MATCHING RESOURCE\n");
					dprint(            "build_cmd: This is a resouce handle to the resource matching the selectstr $::opt_s.\n"
					);
					print($div. "\n");
					$cmd =
					  "$command$flagv -s '$pdomainSel && $res'$flagd $resourceClass";
					dprint(            "build_cmd: Calling run_command with $cmd to display the resource with handle $res\n"
					);
					run_command($cmd, 1, 0);
					print("\n");

					# If this is a frame and -a is specified with an attribute of class
					# IBM.hw_element, or -a not specified:
					#
					if ($resourceClass eq $rscs[1]
						&& ($aClass eq $::rscs[0] || !$::opt_a))
					{
						dprint(               "FINDING ALL ELEMENTS LINKED TO THE CURRENT FRAME\n"
						);

						# Find all elements that has a link pointing to this frame.
						#
						$res =~ s/.*= //;
						my @linkList;
						my $currEleRH = "";

						# List all elements
						#
						$cmd =
						  "$command -x -s '$pdomainSel' $::rscs[0] ResourceHandle Element_FrameRH";
						dprint(               "build_cmd: Calling run_cmd with $cmd to list all elements to find elements that are linked to this frame\n"
						);
						my $element = run_command($cmd, 0, 0);
						foreach my $ele (@$element)
						{
							$ele = trim_whitespace($ele);
							if ($ele =~ /ResourceHandle/) { $currEleRH = $ele; }
							elsif ($ele =~ /Element_FrameRH/)
							{
								$ele =~ s/.*= //;
								if ($ele eq $res) {
									push(@linkList, $currEleRH);
								}
							}
						}
						dprint(               "build_cmd: Finished building array of elements linked to the current frame resource\n"
						);

						# Print matching, linked elements.
						#
						foreach my $ele (@linkList)
						{
							$cmd =
							  "$command $flagv -s '$pdomainSel && $ele' $flagd $::rscs[0] $flaga";
							dprint(                  "build_cmd: Calling run_command with $cmd to get the element linked to this frame that has RH $ele\n"
							);
							run_command($cmd, 1, 0);
							print("\n");
						}
					}
				}
				else
				{
					dprint("FINDING ALL OTHER RESOURCES LINKED\n");
					dprint(            "build_cmd: This is a handle to a linked resource $res\n"
					);

					#                    if ($res =~ /Frame_BPA_MTMS/) {}
					#                    else
					{
						$qClass = $linkClass;
						$res =~ (s/.*=/ResourceHandle ==/);
						$cmd =
						  "$command$flagv -s '$pdomainSel && $res' $flagd $qClass$flaga";
						dprint(               "build_cmd: Calling run_command with $cmd to get resource with handle $res\n"
						);
						run_command($cmd, 1, 0);
						print("\n");
					}
				}
			}
		}
		dprint("build_cmd: Returning $::RUNCMD_RC to main\n");
		return $::RUNCMD_RC;
	}

	# Run command and print output if we have a valid resource class.
	#
	$cmd = "$command$flagv$flags$flagd $resourceClass$flaga";
	dprint("build_cmd: QUERYING RESOURCE WITH SELECT STRING $::opt_s\n");
	dprint("calling run_command with $cmd\n");
	run_command($cmd, 1, 1);
	print("\n");
	dprint("build_cmd: Returning $::RUNCMD_RC to main\n");
	return $::RUNCMD_RC;
}

#-------------------------------------------------------------------------#
# trim_whitespace - removes trailing and leading whitespace               #
#-------------------------------------------------------------------------#
sub trim_whitespace
{

	my @out = @_;
	for (@out)
	{
		s/^\s+//;
		s/\s+$//;
	}
	return (wantarray ? @out : $out[0]);
}

#-------------------------------------------------------------------------#
# get_class - returns resource class of attribute                         #
#-------------------------------------------------------------------------#
sub get_class
{
	dprint("In get_class\n");

	#    my $eleStr = "Element_";
	#    my $frameStr = "Frame_";
	#    my $manStr =  "Manager_";
	#    my $domStr = "Domain_";

	#    if    (($_[0]) =~ /^$eleStr/)   { return $::rscs[0]; }
	#    elsif (($_[0]) =~ /^$frameStr/) { return $::rscs[1]; }
	#    elsif (($_[0]) =~ /^$manStr/)   { return $::rscs[2]; }
	#    elsif (($_[0]) =~ /^$domStr/)   { return $::rscs[3]; }
	#    else                            { return ""; }

	my $result = "";
	my $pAttr  = $_[0];
	dprint("get_class: Attribute passed in is $pAttr\n");
	$pAttr =~ s/=.*//;
	$pAttr =~ s/^\W*//;
	$pAttr = trim_whitespace($pAttr);
	foreach my $attr (@::elementAttr)
	{

		if ($pAttr =~ /^$attr/)
		{
			$result = $rscs[0];
			return $result;
		}
	}
	foreach my $attr (@::frameAttr)
	{
		if ($pAttr =~ /^$attr/)
		{
			$result = $rscs[1];
			return $result;
		}
	}
	foreach my $attr (@::managerAttr)
	{
		if ($pAttr =~ /^$attr/)
		{
			$result = $rscs[2];
			return $result;
		}
	}

	#    foreach my $attr (@domainAttr)
	#    {
	#        if($_[0] =~ /^$attr/)
	#        {
	#            $result = $rscs[3];
	#            return $result;
	#        }
	#    }
	return $result;
}

#-------------------------------------------------------------------------#
# get_attributes - returns persistent attributes for a resource class     #
#-------------------------------------------------------------------------#
sub get_attributes
{

	dprint("In get_attributes.\n");
	my $cmd = "lsrsrcdef -d -A p " . $_[0];
	my $attrList = NodeUtils->runrmccmd($cmd, "", "", -1);
	my @resArray;

	# Check for RMC and Resource Manager errors.
	if ($::RUNCMD_RC > 0)
	{
		foreach my $err (@$attrList)
		{
			$err =~ s/.*lsrsrcdef.*: //;
			$err = trim_whitespace($err);
			print($err. "\n");
		}
		exit($::RUNCMD_RC);
	}

	# Got attributes, grab only attribute names.
	shift(@$attrList);
	shift(@$attrList);
	foreach my $attr (@$attrList)
	{
		$attr =~ s/":.*//;
		$attr =~ s/"//;
		if (!($attr =~ /ActivePeerDomain/))
		{
			push(@resArray, $attr);
		}
	}
	dprint("get_attributes: Returning array of attributes to build_cmd.\n");
	return @resArray;

}

#-------------------------------------------------------------------------#
# run_command - Execute command using lsrsrc                              #
#-------------------------------------------------------------------------#
sub run_command
{

	my $displayResult = $_[1];
	my $printError    = $_[2];

	dprint("In run_command.\n");
	$::resource_found = 0;
	dprint("run_command: calling NodeUtils->runrmccmd with $_[0]\n");
	$::rh = NodeUtils->runrmccmd($_[0], "", "", -1);
	dprint("run_command: NodeUtils->runrmccmd returns:\n");
	foreach my $line (@$::rh)
	{
		dprint("$line\n");
	}

	# For testing only
	#    push(@$::rh,"/usr/sbin/rsct/bin/lsrsrc-api: 2612-018 Attribute name -s is not a valid attribute name.");

	if ($displayResult == 0)
	{

		#        #Catches incorrect attribs and all other RM errors.
		#        if($::RUNCMD_RC > 0)
		#        {
		#            foreach my $line(@$::rh)
		#            {
		#                if( ($line =~ /.*?[0-9]{4}-[0-9]{3}.*/) ) {
		#                    #An error caught,ignore and print when getting links
		#                }
		#                else { push(@::validRHList,$line); }
		#            }
		#            return (\@::validRHList);
		#        }
		#       else {
		return ($::rh);

		#        }
	}
	else
	{
		dprint("run_command: calling display_result\n");
		display_result($printError, @$::rh);

		# Catches no matching resouces for selectstr.
		if ($::resource_found == 0)
		{
			dprint("run_command: No resources found, $::resource_found = \n");
			$::MSGSET = 'hwsvrcmd';
			MessageUtils->message('I', 'IMsgNoMatchingResource');
		}
	}

}

#-------------------------------------------------------------------------#
# display_result - Displays the result of the query to STDOUT             #
#-------------------------------------------------------------------------#
sub display_result
{

	dprint("In display_result.\n");

	my $err;
	my $displayError = $_[0];
	shift(@_);

	foreach my $cls (@_)
	{
		$err = $cls;
		$err =~ s/^.*: //;
		$err = trim_whitespace($err);

		if (($err =~ /^[0-9]{4}-[0-9]{3}/))    # Error caught
		{

			# Prevent mutiple instances of error message
			if ($displayError)
			{ #!$::errorCaught) {               #If error was not previous caught
				print($err. "\n");
				$::errorCaught = 1;
			}
		}
		elsif (($cls =~ /resource [0-9]+/))    # Matching resources found.
		{
			$resource_found = 1;
			if (!($::opt_a) && !($::opt_L)) { print($::div. "\n"); }
			else { }
		}
		elsif (   $cls =~ /Resource Persistent Attributes for/
			   || $cls =~ /ActivePeerDomain/)
		{

			# Surpress output
		}
		else { print(trim_whitespace($cls) . "\n"); }    #Print resource.
	}
}

#-------------------------------------------------------------------------#
# Remove -                                                                #
# set_scope - set scope so that commands are ran in the HMC peer domain   #
#-------------------------------------------------------------------------#
sub set_scope
{

	my $cmd =
	  "lsrsrc -x -s 'ActivePeerDomain==\"ClusterPeerDomain\"' IBM.PeerNode Name";
	my $hmcList = "";
	my $rh      = "";

	$ENV{'CT_MANAGEMENT_SCOPE'} = 3;

	#NodeUtils->runrmccmd("export CT_MANAGEMENT_SCOPE=3","","",-1);
	$rh = NodeUtils->runrmccmd($cmd, "", "", -1);

	if ($::RUNCMD_RC > 0)
	{
		foreach my $err (@$rh)
		{
			$err =~ s/.*lsrsrc.*://;
			$err = trim_whitespace($err);
			print($err. "\n");
			exit($::RUNCMD_RC);
		}
	}
	elsif (@$rh == 0)
	{
		$::MSGSET = 'hwsvrcmd';
		MessageUtils->message('I', 'IMsgNoNodeInPDomain');
		exit(0);
	}

	# unset CT_MANAGEMENT_SCOPE;
	$ENV{'CT_MANAGEMENT_SCOPE'} = "";

	#NodeUtils->runrmccmd("unset CT_MANAGEMENT_SCOPE","","",-1);

	# Get rid of everything besides the hostname and put hostnames in a
	# comma separated list.
	#
	foreach my $attr (@$rh)
	{
		if (($attr =~ /resource [0-9]+/)) { }
		else
		{
			$attr =~ s/\"\z//;
			$attr =~ s/^.*= \"//;
			if ($hmcList ne "") { $hmcList .= ","; }
			$hmcList .= $attr;
		}
	}

	# Removed - CT_CONTACT should not be set if the command is run on the
	# management server and the hmcs are in the management domain
	# which is in our case.  Previously needed to be set when the MS and
	# hmcs were not in the same management domain.
	#$ENV{'CT_CONTACT'} = $hmcList;
}

#-------------------------------------------------------------------------#
# start main body of code                                                 #
#-------------------------------------------------------------------------#

use strict;

# for development use -- redirects where to look for other CSM files
BEGIN { $::csmpm = $ENV{'CSM_PM'} ? $ENV{'CSM_PM'} : '/opt/csm/pm'; }

# Set management domain scope
$ENV{'CT_MANAGEMENT_SCOPE'} = 3;

use Getopt::Std;
use lib $::csmpm;
require NodeUtils;

$::BIN        = '/opt/csm/bin';
$::MSGCAT     = 'HCnodecmds.cat';
$::MSGMAPPATH = '/opt/csm/msgmaps';
$::MSGSET     = 'common';

chop(my $PROGNAME = `/bin/basename $0`);
my $logfile = "/var/log/csm/$PROGNAME.log";

$::rc = 0;
parse_args();

if (defined($::opt_v))
{
	MessageUtils->start_logging($logfile);
	$::logging++;
}

dprint("MAIN: calling build_cmd()\n");
$::rc = build_cmd();
dprint("MAIN: build_cmd returned $::rc\n");

exit($::rc);

END
{
	if ($::logging > 0)
	{
		MessageUtils->stop_logging();
	}
}
