#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 1999,2019 
# 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 
#"@(#)93   1.14   src/rsct/utils/cli/bin/lsclcfg.perl, cucli, rsct_rady, rady2035a 9/24/15 10:02:08"
######################################################################
#                                                                    #
# Module: lsclcfg                                                    #
#                                                                    #
# Purpose:                                                           #
#   lsclcfg - Lists (displays) cluster configuration information     #
#             for this node.                                         #
#                                                                    #
# Syntax:                                                            #
#   Current Usage:                                                   #
#   lsclcfg [-h] [-c] [-l|-d|-D delimitter] [-x] [-V]                #
#   lsclcfg -r [-l|-d|-D delimitter] [-x] [-V] Cluster               #
#                                                                    #
#   Future Usage:                                                    #
#   lsclcfg [-h] [-a|-c|-r] [-l|-d|-D delimitter] [-x] [-V]          #
#   lsclcfg -r [-l|-d|-D delimitter] [-x] [-V] Cluster               #
#                                                                    #
# Flags:                                                             #
#   -h      help - writes this command's usage statement to stdout   #
#   -a      Not supported in this release.                           #
#           Display the cluster information associated with all the  #
#           cluster definitions for this node. A node can be         #
#           defined as belonging to a specific cluster or as an      #
#           Independent Workstation (IW). Where a node can be        #
#           defined as both a member of a cluster or as an IW it can #
#           only be online (or online pending) in one.               #
#   -c      Default. Display the current cluster information         #
#           associated with this node. A node can be defined as      #
#           belonging to a specific cluster or as an Independent     #
#           Workstation (IW). Where a node can be defined as both    #
#           a member of a cluster or as an IW it can only be online  #
#           (or online pending) in one. That one is the current      #
#           cluster.                                                 #
#   -r      Not supported in this release.                           # 
#           Display the list of System Registry Servers in the       #
#           current cluster or in the specified cluster where this   #
#           node is defined.                                         #
#   -l      Long formatted output, one entry per line. This flag     #
#           overrides the -d, -D flags.                              #
#   -d      Delimitter formatted output. The default delimiter is    #
#           a colon ":", use the -D flag if you wish to change       #
#           the default delimiter.                                   #
#   -D delimiter    Delimiter formatted output using the specified   #
#           delimiter. Use this flag to specify something other than #
#           the default colon ":", when the data to be displayed     #
#           may contain colons. Use this flag to specify a one or    #
#           more character delimitter.                               #
#   -x      Exclude printing of the header. When this flag is        #
#           specified the header will not be displayed in the output.#
#   -T      Trace. IBM Support Center use only.                      #
#   -V      Verbose.                                                 #
#                                                                    #
# Operands:                                                          #
#   Cluster         The name of a cluster. A Cluster operand will    #
#                   only be accepted when used with the -r flag.     #
#                   Use this to specify another cluster where this   #
#                   node is defined to find the list of system       #
#                   registry servers associated with the specified   #
#                   cluster.                                         #
#                   TODO: Test this when we can work between         #
#                   clusters. Warning use of this operand has not    #
#                   yet been tested.                                 #
#                                                                    #
# Description:                                                       #
#   TODO: Need to determine if any flavor of this command should be  #
#   shipped in 9/00 or 3/01.                                         #
#                                                                    #
#   TODO: If this command should get shipped and we expect it to     #
#   also be in 3/01 we should use the CT_cli_display_utils.pm.       #
#   To display the information.                                      #
#                                                                    # 
#   The lsclcfg command displays local cluster configuration         #
#   information related to the node where this command is run. The   #
#   data displayed by the command is really just local configuration #
#   data. Data that needs to be available before all the daemons     #
#   associated with the cluster are up and running.                  #
#                                                                    #
#   A node can be defined as belonging to a specific cluster or as   #
#   an Independent Workstation (IW). Where a node can be defined as  #
#   both a member of a cluster or as an IW it can only be online     #
#   (or online pending) in one. For example, if a node is online in  #
#   cluster foo then it is not acting as an IW. If a node is acting  #
#   as an IW than it is not online in any cluster.                   #
#                                                                    #
#   lsclcfg -c displays information about the current cluster,       #
#   the cluster that this node is online or online pending.          #
#   This includes information like the name of the cluster, the      #
#   cluster id and this node's node number which is a unique number  #
#   associated with this node in this cluster.                       #
#                                                                    #
#   The -a flag is not supported in this release.                    #
#   lsclcfg -a displays cluster information associated with all      #
#   of the cluster definitions for this node. This includes          #
#   the cluster name and id.                                         #
#                                                                    #
#   The -r flag is not supported in this release.                    #
#   lsclcfg -r displays information about the system registry        #
#   servers associated with either the current cluster (by default)  #
#   or a specified cluster name.  The specified cluster name must    #
#   be a cluster name where this node is defined.                    #
#   Use lsclcfg -a to get a list of clusters where this node is      #
#   defined. This includes information like the system registry      #
#   server host name, IP address, and port number.                   #
#                                                                    #
# Exit Values:                                                       #
#   0  CU_CLI_SUCCESS        Command completed successfully.         #
#   1  CU_CLI_RMC_ERROR      Command terminated due to an underlying #
#                            Cluster Utils error.                    #
#   2  CU_CLI_ERROR          Command terminated due to an underlying #
#                            error in the command script.            #
#   3  CU_CLI_BAD_OPERAND    Command terminated due to user          #
#                            specifying a bad operand.               #
#   4  CU_CLI_BAD_FLAG       Command terminated due to user          # 
#                            specifying an invalid flag.             #
#   5  CU_CLI_USER_ERROR     Command terminated due to a user error. #
#                            For example specifying an undefined     #
#                            Resource name as the Resource operand.  #
#                                                                    #
# Examples:                                                          #
#   lsclcfg                                                          #
#   lsclcfg -D::                                                     #
#   lsclcfg -a -dx                                                   #
#   lsclcfg -lr Cluster2                                             #
#                                                                    #
# Man Page:                                                          #
#   For the most current detailed description of this command see    #
#   the lsclcfg man page in /opt/rsct/man.                      #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#   /opt/rsct/msgmaps/cucli.lsclcfg.map - message mapping       #
#                                                                    #
# Outputs:                                                           #
#   stdout - display of the directory list.                          #
#   stderr - any error message.                                      #
#                                                                    #
# External Ref:                                                      #
#   Commands: ctdspmsg                                               #
#   Modules:  CU_cli_utils.pm, CU_cli_rc.pm                          #
#   Extensions:  CT::CU.pm                                           #
#   Perl library routines: Getopt::Std                               #
#                                                                    #
# Tab Settings:                                                      #
#   4 and tabs should be expanded to spaces before saving this file. #
#   in vi:  (:set ts=4  and   :%!expand -4)                          #
#                                                                    #
# Change Activity:                                                   #
#   990409 SAB 48413: Initial design & write.                        #
#   011212 JAC 78957: Let -a work and replace cfg file name.         #
#   021212 DS  89145: lsclcfg command without perl extensions        #
#   030224 JAC 92077: Rework current cluster method.                 #
#   051102 JAC 129508: Strip leading/trailing blanks from current    #
#                      cluster name (directory name).                #
#   051118 JAC 131295: Fix how CT_CLUSTER_NAME is processed.         #
######################################################################

#--------------------------------------------------------------------#
# General Program Flow/Logic:                                        #
#                                                                    #
# A. Parse command line flags and operands, determine which flavor   #
#    of this command we are actually invoking.                       #
#    1. Listing current cluster information.                         #
#       A node can be defined in multiple clusters but only online   #
#       (or online pending) in one, this is the current cluster.     #
#    2. Listing all the clusters where this node is defined.         #
#    3. Listing the system registries (when registry is replicated   #
#       there will be more than one in the list) in the specified    #
#       cluster or for the current cluster when no cluster name is   #
#       specified. If a cluster name is specified it must be one of  #
#       the clusters that this node is defined to.                   #
#       TODO: When we have a multi node cluster make sure that       #
#       the cluster utility gives a bad rc for a bad cluster name.   #
# B. Based on which flavor of the command we are using, set up       #
#    the appropriate cluster utility structures and call the         #
#    appropriate extensions.                                         #
#    TODO: For now when we list all of the cluster that a node is    #
#    defined to we are reading the /var/ct/dcm/cfg/clusters file.    #
#    We shouldn't read this file directly since its format will      #
#    eventually be binary. In the future we should call a yet to     #
#    be written cluster utility to do this.                          #
# C. Format the output depending again on which flavor of this       #
#    command we are running (-c, -a, -r).                            #
# D. Cleanup.                                                        #
#--------------------------------------------------------------------#

#--------------------------------------------------------------------#
# Included Libraries and Extensions                                  #
#--------------------------------------------------------------------#
use lib "/opt/rsct/pm";
use locale;
use Getopt::Std; 

use CT_cli_utils qw(printIMsg
					printEMsg);

#use CT::CU;
#use CT::CU qw(  get_cluster_info 
#                get_registry_server_list
#                free_registry_server_list);

use CU_cli_rc qw(CU_CLI_UTILS_ERROR CU_CLI_BAD_FLAG
                 CU_CLI_BAD_OPERAND CU_CLI_USER_ERROR);
use CU_cli_utils qw(host printCEMsg);


#--------------------------------------------------------------------#
# Global Variables                                                   #
#--------------------------------------------------------------------#
$TRUE = 1;
$FALSE = 0;

$Verbose = $FALSE;                      # default - verbose turned off
$Trace = $FALSE;

# By default output is written in tabular (table) form,
#   not long form (one entry per line) and not with delimitters.
$Opt_Long_Format = $FALSE;              # default - see -l (long form)
$Opt_Delm_Format = $FALSE;              # default - see -d (delimitter)
$Opt_Delm_Str = ":";                    # default - see -D (colon :) 
$Opt_No_HDR = $FALSE;                   # default - see -x
$Opt_Current = $TRUE; 
$Opt_All = $FALSE; 
$Opt_SR = $FALSE;

$PROGNAME = "lsclcfg";                  # Program Name for messages
$MSGCAT = "cucli.cat";                  # This cmds message catalogue

$CTDIR = "/opt/rsct";              # RSCT root directory
$CTBINDIR = "$CTDIR/bin";               # Cluster Bin directory path
$LSMSG = "$CTBINDIR/ctdspmsg";          # list / display message rtn
$ENV{'MSGMAPPATH'} = "$CTDIR/msgmaps";  # msg maps used by $LSMSG

#--------------------------------------------------------------------#
# Main Code                                                          #
#--------------------------------------------------------------------#

# parse the command line, exit if there are errors 
($rc, $cluster_name) = &parse_cmd_line;
($rc == 0) || exit $rc;

# Get and display Current Cluster information 
# A node can be defined in multiple clusters but can only be 
# online or online pending in one. That one is the current cluster 
if ($Opt_Current) {
    # Create a Perl object of type cluster_info_t to store the 
    # cluster information  
    #$cluster_info = CT::CU::cluster_info_t->new;

    # Get the Cluster Information
    #($Trace) && print STDERR "Calling CT::CU::get_cluster_info\n";
    #$rc = CT::CU::get_cluster_info($cluster_info);
    #($Trace) && print STDERR "Return  CT::CU::get_cluster_info\n";
    #($rc == 0) || exit CU_CLI_UTILS_ERROR;

    # Display Information associated with the current cluster 
    #formatCurrentClusterInfo($cluster_info);
    &get_cluster_info_a(1);
    #($cu_cluster_name_a, $cu_cluster_id_a, $cu_node_number_a) = &get_current_cluster_info;
    formatCurrentClusterInfo($cu_node_number_a, $cu_cluster_id_a, $cu_cluster_name_a);
}

# Get and display the list of clusters where this node has
# been defined. A node can be defined to more than one cluster.
if ($Opt_All) {
    # TODO: temporary how we get the list of clusters
    # there should be a real cluster utility that does this
    # in ct_cu.h for now we read /var/ct/dcm/cfg/clusters file.
    @cluster_def_list = get_cluster_defs();

    formatClusterDefList(@cluster_def_list);
}

# Get and display information regarding System Registries for
# the specified cluster. There can be more than one registry server
# that will run in a cluster since replication is important for
# high availability.
if ($Opt_SR) {
    # If a cluster name is not specified as the command operand then
    # assume we are interested in the current cluster.
    if (!$cluster_name) {                  # No cluster name.
        $cluster_name = &currentCluster();
    }

    # Create a Perl object of type registry_server_list_t to store the
    # system registry server list
    $registry_server_list = CT::CU::registry_server_list_t->new;

    # Get the System Registry Server List for the specified cluster
    ($Trace) && print STDERR "Calling CT::CU::get_registry_server_list\n";
    $rc = CT::CU::get_registry_server_list($cluster_name, 
        $registry_server_list);
    ($Trace) && print STDERR "Return  CT::CU::get_registry_server_list\n";
    ($rc == 0) || exit CU_CLI_UTILS_ERROR;

    # Display the list of System Registries available in this cluster
    formatClusterSRList($cluster_name, $registry_server_list);

    ($Trace) && print STDERR "Calling CT::CU::free_registry_server_list\n";
    $rc = CT::CU::free_registry_server_list($registry_server_list);
    ($Trace) && print STDERR "Return  CT::CU::free_registry_server_list\n";
    ($rc == 0) || exit CU_CLI_UTILS_ERROR;
}

# Cleanup 

#--------------------------------------------------------------------#
# End Main Code                                                      #
#--------------------------------------------------------------------#


#--------------------------------------------------------------------#
# parse_cmd_line - Parse the command line for options and operands.  #
#   Set appropriate global variables as outlined below, make sure we #
#   have a valid combination of arguments / options.                 #
#                                                                    #
# Return:                                                            #
#   $rc   0                  Command line parsed fine, no problem.   #
#         SR_CLI_BAD_FLAG    Command line contained a bad flag.      #
#                                                                    #
# Global Variables Modified:                                         #
#   $Opt_Current       output   True (-c) print current cluster info #
#   $Opt_ALL           output   True (-a) print all clusters where   #
#                               the node is defined.                 #
#   $Opt_SR            output   True (-r) print system reg list      #
#   $Opt_Long_Format   output   True (-l) print one entry per line   #
#   $Opt_Delm_Format   output   True (-d|-D) print delimitter        #
#                               separated output.                    #
#   $Opt_Delm_Str      output   the string to use as the delimitter, #
#                               default is colon (:).                #
#   $Opt_No_HDR        output   True (-x) print without header       #
#   $Trace             output   True (-T) turns Trace mode on.       #
#   $Verbose           output   True (-V) turn Verbose mode on.      #
#--------------------------------------------------------------------#
sub parse_cmd_line 
{
my(@original_argv) = @ARGV;
my %opts = ();
my $cluster_name;

$cluster_name = "";

# Process the command line...
# Note: Change from GSI to SSI cluster - not supporting -a and -r
# flags for first release of RSCT. The code to support this has not
# been removed just not allowing it through getopts and changed 
# this commands usage statement to show this.  
# if (!&getopts('hacrdD:lxV', \%opts)) {   # Gather options; if errors
if (!&getopts('hacdD:lxVT', \%opts)) {   # Gather options; if errors
    &print_usage;                        # display proper usage
    return CU_CLI_BAD_FLAG;              # return bad rc - bad flag 
}

# Check for invalid combinations of flags and operands
# Cannot have a combination of -a, -c, -r only -a or -c or -r
if (defined $opts{a} && defined $opts{c}) { 
    printCEMsg("EMsgCUcliImproperUsageCombination", "-a", "-c");
    &print_usage;    
    return CU_CLI_BAD_FLAG;
}
if (defined $opts{a} && defined $opts{r}) {
    printCEMsg("EMsgCUcliImproperUsageCombination", "-a", "-r");
    &print_usage;    
    return CU_CLI_BAD_FLAG;
}
if (defined $opts{c} && defined $opts{r}) {
    printCEMsg("EMsgCUcliImproperUsageCombination", "-c", "-r");
    &print_usage;    
    return CU_CLI_BAD_FLAG;
}

# There should be no operands specified unless -r flag specified
if (!defined $opts{r} && $#ARGV >= 0) { 
    printCEMsg("EMsgCUcliImproperUsageOperand", @ARGV);  
    &print_usage;
    return CU_CLI_BAD_OPERAND;          # return nogood - bad operand
}

# If an operand is specified with the -r flag make sure they
# only pass in one operand. 
# TODO: Maybe in the future we accept multiple cluster names.
if (defined $opts{r} && $#ARGV >= 0) {
    $cluster_name = $ARGV[0];
    if ($#ARGV >= 1) {                  # more than one operand
        printCEMsg("EMsgCUcliImproperUsageOperand", $ARGV[1]);
        &print_usage;    
        return CU_CLI_BAD_OPERAND;      # no good - too many operands
    }
}

# See which options/flags were used...
if (defined $opts{h}) {                 # -h, help request  
    &print_usage;                       # print usage statement
    exit(0);                            # all done with good return!
}

# The -l flag has higher precedence over the -d flag which has
# higher precedence over the -D flag

if (defined $opts{D}) {                 # -D <delimitter> format
    $Opt_Delm_Format = $TRUE;
    $Opt_Long_Format = $FALSE;
    $Opt_Delm_Str = $opts{D};
}

if (defined $opts{d}) {                 # -d delimitter format
    $Opt_Delm_Format = $TRUE;
    $Opt_Long_Format = $FALSE;
    $Opt_Delm_Str = ":";
}

if (defined $opts{l}) {                 # -l long format, 1 entry/line
    $Opt_Long_Format = $TRUE;
    $Opt_Delm_Format = $FALSE;
}
 
if (defined $opts{x}) {
    $Opt_No_HDR = $TRUE;                # -x do not print header
}

if (defined $opts{a}) {
    $Opt_All = $TRUE;
    $Opt_Current = $FALSE;
}

if (defined $opts{c}) {
    $Opt_Current = $TRUE;
}

if (defined $opts{r}) {
    $Opt_SR = $TRUE;
    $Opt_Current = $FALSE;
}

if (defined $opts{T}) {
    $Trace = $TRUE;                     # -T trace
}

if (defined $opts{V}) {                 # -V verbose 
    $Verbose = $TRUE;
}

return(0, $cluster_name);               # success
}   # end parse_cmd_line


#--------------------------------------------------------------------#
# print_usage : print the usage statement (syntax) to stdout.        #
# current usage: lsclcfg [-h] [-c] [-l|-d|-D delimitter] [-x] [-TV]  #
# future  usage: lsclcfg [-h] [-a|-c|-r] [-l|-d|-D delimitter] [-x]  #
#                        [-TV]                                       #
#                lsclcfg -r [-l|-d|-D delimitter] [-x] [-TV]         #
#                        Cluster_Name                                #
#--------------------------------------------------------------------#
sub print_usage
{
printIMsg("IMsglsclcfgUsage");
}   # end print_usage


#--------------------------------------------------------------------#
# get_cluster_defs - reads the /var/ct/dcm/cfg/clusters file         #
#   to build a list of all of the cluster names and ids that this    #
#   node is defined.                                                 #
#   TODO: This function is a hack right now. It should not be        #
#   directly reading this information from this file but should      #
#   be calling a cluster utility to get that information.            #
#                                                                    #
# Return:                                                            #
#   @cluster_def_list   The list of clusters where this node is      #
#                       defined.                                     #
#--------------------------------------------------------------------#
sub get_cluster_defs 
{
my($cfg_file, @cluster_defs);

# TODO: This is a temporary way to get the list of clusters that 
# this node (node where running command) are defined. 
$cfg_file = "</var/ct/cfg/clusters";

# TODO: this open should be removed when libct_cu.a supports this
# Not a catalogued message since this is temporary code
open(CFGIN, $cfg_file) ||
    die "Can't open Cluster Configuration file: $cfg_file\n";

while (<CFGIN>) {
# If problems reading the file or file empty just return a NULL 
# array, since this is a hack we aren't going to write error messages
# that can be done by the real code
    push @cluster_defs, [ split ]; 
}   # end get_cluster_defs

return (@cluster_defs);
}   # end get_cluster_defs


#--------------------------------------------------------------------#
# currentCluster - return the current cluster name for the node      #
#   where this command is running. The current cluster is the        #
#   cluster where this node is online. A node can be defined in      #
#   more than one cluster but only online in one.                    #
#                                                                    #
# Return:                                                            #
#   $cluster_name      The cluster name                              #
#                                                                    #
# Global References:                                                 #
#   $Trace             input  Turns tracing of extension calls on.   #
#--------------------------------------------------------------------#
sub currentCluster
{
# Create a Perl object of type cluster_info_t to store the
# cluster information
$cluster_info = CT::CU::cluster_info_t->new;

# Get the Cluster Information to get the cluster name
($Trace) && print STDERR "Calling CT::CU::get_cluster_info\n";
$rc = CT::CU::get_cluster_info($cluster_info);
($Trace) && print STDERR "Return  CT::CU::get_cluster_info\n";
($rc == 0) || exit CU_CLI_UTILS_ERROR;

return(CT::CU::cluster_info_t::get_cluster_name($cluster_info));
}   # end currentCluster


#--------------------------------------------------------------------#
# formatCurrentClusterInfo - displays information associated with    #
#   the current cluster using the appropriate output format (long,   #
#   delimitter, or tabular).                                         #
#   TODO: this and the other format functions need to be converted   #
#   to use the CT_cli_display_utils.                                 #
#                                                                    #
# Parameters:                                                        #
#   $cluster_info   input  The Cluster Information                   #
#                                                                    #
# Global References:                                                 #
#   Opt_Long_Format - input - TRUE if should display one per line.   #
#   Opt_Delm_Format - input - TRUE if should display with delimiter. #
#   Opt_Delm_Str    - input - Actual delimiter to display with.      #
#   Opt_No_HDR      - input - TRUE if should not display header.     #
#--------------------------------------------------------------------#
sub formatCurrentClusterInfo
{
#local($cluster_info) = @_;
my($node_number, $cluster_id, $cluster_name)=@_;

# display header
if (!$Opt_No_HDR) {
    if ($Opt_Delm_Format) {
        # display delimitted formatted header
        printIMsg("IMsglsclcfgClCurDelmHdr", $Opt_Delm_Str);
    }
    elsif (!$Opt_Long_Format) {
        # display tabular formatted header
        printIMsg("IMsglsclcfgClCurTblHdr");
    }
}

#$cluster_name = CT::CU::cluster_info_t::get_cluster_name($cluster_info);
#$cluster_id = CT::CU::cluster_info_t::get_cluster_ID($cluster_info);
#$node_number = CT::CU::cluster_info_t::get_node_number($cluster_info);

if ($Opt_Long_Format) {
    # Display cluster information in Long format
    printIMsg("IMsglsclcfgClCurLongTempl",
        $cluster_name, $cluster_id, $node_number);
}
elsif ($Opt_Delm_Format) {
    # Display cluster information in delimitter format 
    print $cluster_name, $Opt_Delm_Str, 
            $cluster_id, $Opt_Delm_Str,
            $node_number, $Opt_Delm_Str, "\n";
}
else  {
    # Display cluster information in table format
    # TODO: It would have been nice to have put the next message in 
    # a message catalogue but AIX dspmsg does not support
    # fancy conversions strings like -14s.
    printf("%-24s %-24s %ld \n", $cluster_name, $cluster_id, $node_number);
}
}   # end formatCurrentClusterInfo


#--------------------------------------------------------------------#
# formatClusterDefList - displays the list of clusters that this     #
#   node is defined.                                                 #
#                                                                    #
# Parameters:                                                        #
#   $cluster_def_list  input  The list of clusters where this node   #
#                             is defined.                            #
#                                                                    #
# Global References:                                                 #
#   Opt_Long_Form - input - TRUE if should display one per line.     #
#   Opt_Delm_Form - input - TRUE if should display with delimiter.   #
#   Opt_Delm_Str  - input - Actual delimiter to display with.        #
#   Opt_No_HDR    - input - TRUE if should not display header.       #
#--------------------------------------------------------------------#
sub formatClusterDefList
{
local(@cluster_defs) = @_;
my($array_ref, $cluster_id, $cluster_name, $i); 

# display header
if (!$Opt_No_HDR) {
    if ($Opt_Delm_Format) {
        # display delimitted formatted header
        printIMsg("IMsglsclcfgClDefDelmHdr", $Opt_Delm_Str);
    }
    elsif (!$Opt_Long_Format) {
        # display tabular formatted header
        printIMsg("IMsglsclcfgClDefTblHdr");
    }
}

# print the data
$i = 0;
for $array_ref (@cluster_defs) {
    $cluster_id = $array_ref->[0];
    $cluster_name = $array_ref->[1];

    if ($Opt_Long_Format) {
        # Display cluster information in Long format
        ($i > 0) && print "\n";         # separate multiple entries
        printIMsg("IMsglsclcfgClDefLongTempl", $cluster_name,
            $cluster_id);
    }
    elsif ($Opt_Delm_Format) {
        # Display cluster information in delimitter format
        print $cluster_name, $Opt_Delm_Str,
            $cluster_id, $Opt_Delm_Str, "\n";
    }
    else  {
        # Display cluster information in table format
        # It would have been nice to have put the next message in
        # a message catalogue but AIX dspmsg does not support
        # fancy conversions strings like -14s.
        printf("%-24s %-24s\n", $cluster_name, $cluster_id);
    }
    $i++;
}

}   # end formatClusterDefList   


#--------------------------------------------------------------------#
# formatClusterSRList - displays the system registry server list     #
#   for the previously specified cluster.                            #
#                                                                    #
# Parameters:                                                        #
#   $cluster_name         input  The cluster name.                   #
#   $registry_server_list input  The registry server list.           #
#                                                                    #
# Global References:                                                 #
#   Opt_Long_Form - input - TRUE if should display one per line.     #
#   Opt_Delm_Form - input - TRUE if should display with delimiter.   #
#   Opt_Delm_Str  - input - Actual delimiter to display with.        #
#   Opt_No_HDR    - input - TRUE if should not display header.       #
#--------------------------------------------------------------------#
sub formatClusterSRList
{
local($cluster_name, $registry_server_list) = @_;
my($sr_ip_address, $sr_port_number, $sr_server_name);
my($num_entries, $i);

# Print the header information (for delimitter & tabular output)
if (!$Opt_No_HDR) {
    if ($Opt_Delm_Format) {
        printIMsg("IMsglsclcfgSRDelmHdr", $Opt_Delm_Str);
    }
    elsif (!$Opt_Long_Format) {
        printIMsg("IMsglsclcfgSRTblHdr");
    }
}

$num_entries = CT::CU::registry_server_list_t::get_list_size($registry_server_list);
for ($i = 0; $i < $num_entries; $i++) {
    $sr_ip_address = CT::CU::registry_server_list_t::get_ip_address(
        $registry_server_list, $i);
    $sr_port_number = CT::CU::registry_server_list_t::get_port_number(
        $registry_server_list, $i);
    $sr_server_name = host($sr_ip_address);

    if ($Opt_Long_Format) {
        # Display cluster information in Long format
        ($i > 0) && print "\n";         # separate multiple entries
        printIMsg("IMsglsclcfgSRLongTempl", $cluster_name,
            $sr_server_name, $sr_ip_address, $sr_port_number);
    }
    elsif ($Opt_Delm_Format) {
        # Display cluster information in delimitter format
        print $cluster_name, $Opt_Delm_Str,
            $sr_server_name, $Opt_Delm_Str,
            $sr_ip_address, $Opt_Delm_Str,
            $sr_port_number, $Opt_Delm_Str, "\n";
    }
    else  {
        # Display cluster information in table format
        # It would have been nice to have put the next message in
        # a message catalogue but AIX dspmsg does not support
        # fancy conversions strings like -14s.
        printf("%-24s %-24s %-16s %ld \n", $cluster_name,
            $sr_server_name, $sr_ip_address, $sr_port_number);
    }
}   # end for $num_entries

}   # end formatClusterSRList

#--------------------------------------------------------------------#
# get_cluster_info_a - gets the cluster info                         #
#                                                                    #
# Parameters:                                                        #
#   $omit_foreign         input  foriegn defs flag.                  #
# 								     #
# set the values for the variables                                   #
#    cu_node_number_a cu_cluster_id_a cu_cluster_name_a              #
#    from the cfg file						     #
#--------------------------------------------------------------------#
sub get_cluster_info_a
{
   $omit_foriegn_flg=0;
   if (@_)
   {
      #when omit_foriegn_flg=1, it will return IW, if the current cluster
      #was created by non=ConfigRM
      $omit_foriegn_flg=@_;
   }
   $CT_CURRENT_CFGFILE="/var/ct/cfg/current_cluster";
   $CT_NODEDEF_SUBSTRING="/var/ct/";

   #First check to see if cluster name is defined in the environment
   #If so, it overrides the current cluster pointer
   $my_var=$ENV{'CT_CLUSTER_NAME'};

   $line="";
   # if ENV for CT_CLUSTER_NAME is not set
   if ((!defined($my_var)))
   {
     #Environment variable is not defined so use current cluster pointer
     #Open the file containing the current cluster name
     open(CLU_FILE,$CT_CURRENT_CFGFILE) || die printEMsg("EMsgErrorFileOpen",$!,$CT_CURRENT_CFGFILE); 
     # Read the cluster id from the file(it also works if this is the cluster name
     while (<CLU_FILE>)
     {
       $line=$_;
     }
     close CLU_FILE;
     chomp $line;
   }
   else
   {
      #open(CLU_FILE,$my_var) || die printEMsg("EMsgErrorFileOpen",$!,$my_var); 
      #while (<CLU_FILE>)
      #{
      #  $line=$_;
      #}
      #close CLU_FILE;
      #chomp $line;
      $line = $my_var;    # defect 131295
   }
   # strip leading and trailing blanks from current cluster name - defect 129508
   $line =~ s/^\s//; 
   $line =~ s/\s$//; 
   # construct the path to the nodedef file for the selected cluster
   $CT_NODEDEF_SUBSTRING=$CT_NODEDEF_SUBSTRING.$line."/cfg/nodedef.cfg";
   # Open the nodedef file
   open(CLU_FILE,$CT_NODEDEF_SUBSTRING) || die printEMsg("EMsgErrorFileOpen",$!,$CT_NODEDEF_SUBSTRING); 
   while (<CLU_FILE>)
   {
      $line=$_;
   }
   close CLU_FILE;
   chomp $line;
   ($cu_node_number_a,undef, undef, $cu_cluster_id_a, $cu_cluster_name_a, undef)=split(" ", $line);
   if ( (length($cu_node_number_a) == 0) || (length($cu_cluster_id_a) == 0) || (length($cu_cluster_name_a) ==0) )
   {
      printEMsg("EMsgParsingConfigFile", $CT_NODEDEF_SUBSTRING);
      exit (1);
   }

   # Non-ConfigRM's custer ID will contain "-"
   # The node is not in IW. So, we need to verify whether it is by non-ConfigRM
   # We need to re-read the nodedef using "IW" 
   if ( ($omit_foriegn_flg != 0) && ($cu_cluster_name_a ne "IW") && ((index($cu_cluster_id_a,"-"))>=0) )
   {
      #Construct the path to the nodedef file for the selected cluster
      $CT_NODEDEF_SUBSTRING="/var/ct/";
      $CT_NODEDEF_SUBSTRING=$CT_NODEDEF_SUBSTRING."IW/cfg/nodedef.cfg";
      #Open the nodedef file
      open(CLU_FILE,$CT_NODEDEF_SUBSTRING) || die printEMsg("EMsgErrorFileOpen",$!,$CT_NODEDEF_SUBSTRING); 
      while (<CLU_FILE>)
      {
         $line=$_;
      }
      close CLU_FILE;
      chomp $line;
      ($cu_node_number_a,undef, undef, $cu_cluster_id_a, $cu_cluster_name_a, undef)=split(" ", $line);
   if ( (length($cu_node_number_a) == 0) || (length($cu_cluster_id_a) == 0) || (length($cu_cluster_name_a) ==0) )
      {
         printEMsg("EMsgParsingConfigFile", $CT_NODEDEF_SUBSTRING);
         exit (1);
      }
   }
}

#--------------------------------------------------------------------#
# get_current_cluster_info - gets the cluster information by using   #
#    the cu_get_cluster_info utility.                                #
#                                                                    #
# Parameters:                                                        #
#   $cluster_name         output  The cluster name.                  #
#   $cluster_id           output  The cluster id.                    #
#   $cluster_num          output  The cluster node number.           #
#                                                                    #
# Global References:                                                 #
#--------------------------------------------------------------------#
sub get_current_cluster_info
{
my $cluster_name = "";                # initialize cluster name
my $cluster_id = "";                  # initialize cluster id
my $cluster_num = "";                 # initialize cluster node number

my @cl_out = ();                      # output from ct_clusterinfo cmd
my $rc = 0;
my $i = 0;
my $title = "";                       # used for parsing


# call ct_clusterinfo to get current cluster information
@cl_out = `$CTBINDIR/ct_clusterinfo -scin 2>&1`;

# capture the return code
$rc = $?;

# show any errors if there was a bad rc
if ($rc != 0) {
   exit CU_CLI_UTILS_ERROR;
}

# sample output like:
#CLUSTER_NAME CLUSTER_ID NODE_NUMBER (no heading)
#IW 6907980 1

# get cluster name
if (defined $cl_out[0]) {
   ($cluster_name, $cluster_id, $cluster_num) = split /\s+/,$cl_out[0];
   $cluster_name =~ s/\s//g;
   $cluster_id =~ s/\s//g;
   $cluster_num =~ s/\s//g;
}

return ($cluster_name, $cluster_id, $cluster_num);

}  # end get_current_cluster_info