
#############################################################################
#
# Copyright Avaya Inc., All Rights Reserved.
#
# THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF Avaya Inc.
#
# The copyright notice above does not evidence any actual or intended
# publication of such source code.
#
# Some third-party source code components may have  been modified from their
# original versions by Avaya Inc.
#
# The modifications are Copyright Avaya Inc., All Rights Reserved.
#
#############################################################################

package PRE_POST_ROUTINE;

require 5.000;
require Exporter;
@ISA	=qw(Exporter);
@EXPORT	=qw( extract_tar_info restore_pwd compare_ecs_variable
	     file_cleanup version_same ecs_merge ecs_append
             crond_file_check update_sched_bkup pe_check
	     log_cmd log_err log_info is_migration_allowed
	     check_disk_root
	    );
@EXPORT_OK	=qw();

use FindBin();
use Fcntl(O_RDWR);
use FopHandle;
use fileop(CreateOpenInfo, OpenMul, CommitMul, AbortMul, LOCK_NOCOPY);

# pre-declare logging functions
sub log_cmd();
sub log_err(@);
sub log_info(@);

# definition of results for is_duplex function
my %duplex_mode = ('simplex'=>0, 'sw_dup'=>1, 'hw_dup'=>2);

## !!!!!!!!!!!!!!!!!!!!!!!!!!!!
##  WARNING -- VERSION_SAME always returns 0
## !!!!!!!!!!!!!!!!!!!!!!!!!!!!
sub version_same
{
	my $tar_version, $cur_version;
	$tar_version=`/opt/ecs/bin/swversion | grep Reports`;
	$tar_version=~s/Reports as: *//;
	chomp $tar_version;
	$cur_version=`grep Version /etc/opt/ecs/ecs.conf.latestversion`;
	$cur_version=~s/Version *//;
	chomp $cur_version;

	open OUTFILE, ">> /var/log/restore_migration";
	print (OUTFILE "restoring $tar_version to $cur_version\n");
	close OUTFILE;
	return 1	if ($tar_version eq $cur_version);
	return 2 	if ($tar_version gt $cur_version);
	return 0;
}

###########################################################################
# extract info from info file of tar file (valid variables CM_VERSION,
# AUDIX-VERSION)
###########################################################################
sub extract_tar_info
{
    local ($bkup_opt_file, $var_search)=(@_);
    my $tar_info_variable;
    my $tar_info_value="";
	# check for valid variable request
	if ($var_search eq "CM_VERSION")
	{
		$CMVERSION_FLG = 1;
		$search_string="SW Version";
	}
	if ($var_search eq "AUDIX_VERSION")
	{
		$AUDIX_FLG = 1;
		$search_string="Audix Version";
	}
	if ($var_search eq "CM_PATCH")
	{
		$CMPATCH_FLG = 1;
		$search_string="Update ID";
	}	
	if (!$CMPATCH_FLG && !$AUDIX_FLG && !$CMVERSION_FLG)
	{
        # put error in system log
        open OUTFILE, ">> /var/log/restore_migration";
        print (OUTFILE "FAILURE: Request for invalid parameter from tar info file \n");
        close OUTFILE;
        return $tar_info_value;
	}
    # get version from tar image name from options file
    $tar_image=`grep TAR_IMAGE $bkup_opt_file 2>/dev/null`;
    $tar_image=~s/^TAR_IMAGE *//;
    chomp $tar_image;
    # ERROR: no options file exist; terminate with error
    if (!(-e $tar_image))
    {
        # put error in system log
        open OUTFILE, ">> /var/log/restore_migration";
        print (OUTFILE "FAILURE: Unable to access tar_image: $tar_image\n");
        close OUTFILE;
        return $tar_info_value;
    }
    # read in values for ecs.conf in tar image
    @tar_info_variable=`tar -zxOf $tar_image *.info  2>/dev/null`;
	if ($#tar_info_variable < 0)
	{
		open OUTFILE, ">> /var/log/restore_migration";
		print (OUTFILE "FAILURE: Unable to access tar_image: $tar_image\n");
		close OUTFILE;
		return $tar_info_value;
	}
	# look for variable and get value
	@tar_tmp_value=grep /$search_string/, @tar_info_variable; 
	if ($#tar_tmp_value < 0)
	{
		open OUTFILE, ">> /var/log/restore_migration";
		print (OUTFILE "FAILURE: CM SW VERSION not found\n");
		close OUTFILE;
		return $tar_info_value;
	}
	if (!$CMPATCH_FLG)
	{
		$tar_info_value=@tar_tmp_value[0]; 
		$tar_info_value=~s/^SW [A-Za-z]* - (.*) - .*/$1/;
		chomp $tar_info_value;
	}
	else
	{
		# may have to extend to get multiple patch listings
		$tar_info_value=@tar_tmp_value[2]; 
	}
	return $tar_info_value;
}

###########################################################################
# extract info from ecs.conf version of tar file
###########################################################################
sub extract_tar_ecs_var
{
	local ($bkup_opt_file, $ecs_var_search)=(@_);
	my $tar_version, $cur_version;
	my $tar_variable_value="";
	# get version from tar image name from options file
	$tar_image=`grep TAR_IMAGE $bkup_opt_file 2>/dev/null`;
	$tar_image=~s/^TAR_IMAGE *//;
	chomp $tar_image;
	# ERROR: no options file exist; terminate with error
	if (!(-e $tar_image))
	{
		# put error in system log
		open OUTFILE, ">> /var/log/restore_migration";
		print (OUTFILE "FAILURE: Unable to access tar_image: $tar_image\n");
		close OUTFILE;
		return $tar_variable_value;
	}
	# read in values for ecs.conf in tar image
	@ecs_variables=`tar -zxOf $tar_image ./etc/opt/ecs/ecs.conf 2>/dev/null`;
	map {"chomp $_"} @ecs_variables;
	$ecs_variables_cnt=@ecs_variables;
	# ecs.conf file is empty; terminate with error
	if (!($ecs_variables_cnt))
    {
		# put error in system log
		print (OUTFILE "FAILURE: Unable to read ecs.conf content\n");
		close OUTFILE;
		return $tar_variable_value;
	}
	# search tar version of ecs file for variable 
	@tar_variable=grep /^$ecs_var_search/,@ecs_variables;
	$tar_variable=@tar_variable;
	# ERROR: variable doesn't exist in tar version of ecs.conf or has more than 1 value
	if (!($tar_variable == 1))
	{
		# put error in system log
		open OUTFILE, ">> /var/log/restore_migration";
		print (OUTFILE "FAILURE: $tar_variable variable is null or has more than one entry in ecs.conf file\n");
		close OUTFILE;
		return $tar_variable_value;
	}
	# variable found return value to calling routine
	chomp $tar_variable[0];
	$tar_variable_value=$tar_variable[0];
	$tar_variable_value=~s/^$ecs_var_search *//;
	return $tar_variable_value;
}

###########################################################################
# compare ecs.conf variable from tar image with current value
###########################################################################
sub compare_ecs_variable
{
	local ($bkup_opt_file, $ecs_var_search)=(@_);
	my $tar_version, $cur_version;
	# get version and duplex mode from tar image
	$tar_image=`grep TAR_IMAGE $bkup_opt_file 2>/dev/null`;
	$tar_image=~s/^TAR_IMAGE *//;
	chomp $tar_image;
	if (!(-e $tar_image))
	{
		open OUTFILE, ">> /var/log/restore_migration";
		print (OUTFILE "FAILURE: Unable to access tar_image: $tar_image\n");
		close OUTFILE;
		return 1;

	}
	@ecs_variables=`tar -zxOf $tar_image ./etc/opt/ecs/ecs.conf 2>/dev/null`;
	map {"chomp $_"} @ecs_variables;
	$ecs_variables_cnt=@ecs_variables;
	if (!($ecs_variables_cnt))
	{
		open OUTFILE, ">> /var/log/restore_migration";
		print (OUTFILE "FAILURE: Unable to read ecs.conf content\n");
		close OUTFILE;
		return 1;
	}
	@tar_variable=grep /^$ecs_var_search/,@ecs_variables;
	$tar_variable=@tar_variable;

	if (!($tar_variable == 1))
	{
		open OUTFILE, ">> /var/log/restore_migration";
		print (OUTFILE "FAILURE: $tar_variable variable is null or has mor than one entry in ecs.conf file\n");
		close OUTFILE;
		return 1;
	}
	chomp $tar_variable[0];
	$tar_variable_value=$tar_variable[0];
	$tar_variable_value=~s/^$ecs_var_search *//;

	# get version from current load
	$cur_variable=`grep $ecs_var_search /etc/opt/ecs/ecs.conf`;
   	chomp $cur_variable;
	$cur_variable_value=$cur_variable;
	$cur_variable_value=~s/^$ecs_var_search *//;
	if ($ecs_var_search eq "Version")
	{
		if ($tar_variable_value gt $cur_variable_value)
		{
			open OUTFILE, ">> /var/log/restore_migration";
			print (OUTFILE "FAILURE: Restore from Version: $tar_variable_value to $cur_variable_value not supported\n");
			close OUTFILE;
			return 2;
		}
	}
	if ($ecs_var_search eq "ServerType")
	{
		# get duplex mode from ecs.conf
		my @tar_duplex_mode=grep /^ServerDuplication/,@ecs_variables;
		my $tar_duplex_number=@tar_duplex_mode;

		if (($tar_duplex_number > 1))
		{
			open OUTFILE, ">> /var/log/restore_migration";
			print (OUTFILE "FAILURE: $tar_duplex_number variable has more than one entry in ecs.conf file\n");
			close OUTFILE;
			return 1;
		}
		chomp $tar_duplex_mode[0];
		$tar_duplex_mode[0]=~s/^ServerDuplication *//;

		# get duplex mode from current load
		my $cur_duplex_mode=`grep "ServerDuplication" /etc/opt/ecs/ecs.conf`;
		chomp $cur_duplex_mode;
		$cur_duplex_mode=~s/^ServerDuplication *//;

		# Check migration permission
		if(is_migration_allowed($tar_variable_value,
		                        $cur_variable_value,
					$tar_duplex_mode[0],
					$cur_duplex_mode))
		{
			# allow restore to server
			return 0;
		}
		else
		{
			open OUTFILE, ">> /var/log/restore_migration";
			# server mismatch; terminate the restore
			print OUTFILE "FAILURE: Migration not allowed for $tar_variable_value and duplex=$tar_duplex_mode[0] to $cur_variable_value and duplex=$cur_duplex_mode; RESTORE TERMINATED\n";
			close OUTFILE;
			return 2;
		}
	}
}

############################################################################
# Function to append ecs variables to the ecs.conf file after ecs_merge
# function has been invoked.
# To append a variable to the ecs.conf file, the following conditions must
# be true:
# 1.) The variable has to be added to the list @append_ecs_vars.
# 2.) The variable must not be present in the merged ecs.conf file
# 3.) The variable must be present in the current (latest) ecs.conf file
# The value of the appended variable will be the same as it was in the
# current (latest) ecs.conf file.
############################################################################
sub ecs_append
{
    my $SUCCESS               =0;
    my $ERR_CANNOT_APPEND     =1;
    my $ERR_NO_ECS_FILE       =2;

    # ecs.conf file after ecs_merge
    my $ECS_MERGED="/etc/opt/ecs/ecs.conf";
    # ecs.conf before restore. File was not touched by ecs_merge
    my $ECS_LATEST="/etc/opt/ecs/ecs.conf.latestversion";

    open OUTFILE, ">> /var/log/restore_migration";
    if (!(-s $ECS_MERGED) || !(-s $ECS_LATEST))
    {
        print (OUTFILE "The file $ECS_MERGED or $ECS_LATEST doesn't exist or
 is empty\n");
        close OUTFILE;
        return $ERR_NO_ECS_FILE;
    }
    @merged_ecs=`cat $ECS_MERGED`;
    @latest_ecs=`cat $ECS_LATEST`;
    @append_ecs_vars=("CMenabled", "SESenabled");

    foreach $append_ecs_var (@append_ecs_vars)
    {
        ####################################################################
        # check whether variable is not in merged ecs.conF
        ####################################################################
        @match_merged=grep /^$append_ecs_var\s+/, @merged_ecs;
        if (!(@match_merged))
        {
            ################################################################
            # check whether variable is in latest ecs.conF
            ################################################################
            @match_latest=grep /^$append_ecs_var\s+/, @latest_ecs;
            if (@match_latest)
            {
                ############################################################
                # append variable, because it is not in merged ecs.conf but
                # in latest ecs.conf
                ############################################################
                chomp $match_latest[0];
                if (system("echo $match_latest[0] >> $ECS_MERGED"))
                {
                    print (OUTFILE "ecs_append: cannot append \"$match_latest[0]\" to ecs.conf\n");
                    close OUTFILE;
                    return $ERR_CANNOT_APPEND;
                }
                else
                {
                    print (OUTFILE "ecs_append: \"$match_latest[0]\" appended to ecs.conf\n");
                }
            }
        }
    }
    close OUTFILE;
    return $SUCCESS;
}

sub ecs_merge
{
	$ECS_TAR="/etc/opt/ecs/ecs.conf";
	$ECS_CUR="/etc/opt/ecs/ecs.conf.latestversion";
	$ECS_WORK="/etc/opt/ecs/ecs.conf.working";
	$ECS_ORGTAR="/etc/opt/ecs/ecs.conf.orgtar";
	####################################################################
	# copy the original tar version of ecs.conf
	####################################################################
	system("cp -p $ECS_TAR $ECS_ORGTAR");                     
	system("cp -p $ECS_CUR $ECS_WORK");                     
	$ECS_NEW="/etc/opt/ecs/ecs.conf.newversion";
	system("cp -p $ECS_CUR $ECS_NEW");			# added so if no diffs between file; then will default to original version                     
	if (!(-s $ECS_TAR) || !(-s $ECS_CUR))
	{
		open OUTFILE, ">> /var/log/restore_migration";
		print (OUTFILE "One of the following files doesn't exist or is empty: $ECS_TAR or $ECS_CUR\n");
		close OUTFILE;
		return(2);
	}
	@diff_list=`diff -b -B $ECS_TAR $ECS_CUR`;
	@diff_tar=grep /< */, @diff_list;
	$diff_cnt=$#diff_tar +1;
	if ($diff_cnt == 0)
	{
		return(0);
	}
	@new_ecs=`cat /etc/opt/ecs/ecs.conf.latestversion`;
	# update new ecs_conf file
	@dont_process=("PatchId","UpdateType","OfferType", "ServerType", "backupDevice", 
                                 "CDA_VINTAGE", "Version", "SESenabled", "CMenabled");
	@add_ecsvar=("PrimaryAddr", "s8500PA" , "srayPA1" , "srayPA2" , "srayPA3" ,
				 "srayPA4");
	open OUTFILE, ">> /var/log/restore_migration";
	foreach $diff_line (@diff_tar)
	{
		$diff_line=~s/< *//;
		chomp $diff_line;
		$diff_keyword=$diff_line;
		$diff_keyword=~s/^(\S*)( *(\S*))*/$1/;
		chomp $diff_keyword;
		$diff_comment=grep /^\#/, $diff_keyword;			# check for comment line
 		#############################################################
		# check to see if line if to NOT to be processed,
		# is a blank line, or is a comment line; if so then do nothing 
		# to entry in ecs.conf file
 		#############################################################
		if ((grep /$diff_keyword/, @dont_process) ||
			($diff_keyword eq "") || ($diff_comment))
		{
			next;
		}
 		##############################################################
		# string found in current ecs.conf file; update value to reflect 
		#  original value in tar version of ecs.conf
 		##############################################################
		$diff_match=grep /$diff_keyword */, @new_ecs;
		if ($diff_match)
		{
			$diff_org=`grep $diff_keyword $ECS_CUR`;
			chomp $diff_org;
			if (system("sed \"/$diff_keyword /c $diff_line\" $ECS_WORK >$ECS_NEW"))
			{
				print (OUTFILE "ecs_merge: unable to modify \"$diff_line\" in $ECS_NEW\n");
				#################################################################
				# replace the ecs.conf file with the version restored during tar
				# to ensure all files at same version; not concerned with failure
				# of copy because system may already be in "undetermined" state
				#################################################################
				system("cp -p $ECS_ORGTAR $ECS_TAR");
				close OUTFILE;
				return(1);
			}
			else 
			{
				print (OUTFILE "ecs_merge: \"$diff_org\" line changed to \"$diff_line\"\n");
				system("cp -p $ECS_NEW $ECS_WORK");                     
				next;
			}
		}
 		#######################################################################
		# Variable is not in current ecs.conf; check to see if it should 
		#  be added (if it exists in the "add_ecsvar" listing)
 		#######################################################################
		if (grep /$diff_keyword/,@add_ecsvar)
		{
			if (system("echo $diff_line >> $ECS_WORK"))
			{
				print (OUTFILE "ecs_merge: adding entry \"$diff_line\" in $ECS_WORK\n");
				close OUTFILE;
				#################################################################
				# replace the ecs.conf file with the version restored during tar
				# to ensure all files at same version; not concerned with failure
				# of copy because system may already be in "undetermined" state
				#################################################################
				system("cp -p $ECS_ORGTAR $ECS_TAR");
				return(1);
			}
			else 
			{
				print (OUTFILE "ecs_merge: \"$diff_line\" added to ecs.conf\n");
				next;
			}
		}
 		#######################################################################
		# NO processing to be done on entry from tar version of ecs.conf
 		#######################################################################
		else 
		{
				print (OUTFILE "ecs_merge: \"$diff_line\" not added to $ECS_NEW\n");
				next;
		}
	}
	# merging completed - retain original tar version of ecs.conf
	system("cp -p $ECS_WORK $ECS_TAR");                     
	print (OUTFILE "ecs_merge: ecs.conf updated");
	close OUTFILE;
	return 0;
}


############################################################################
# Function to check the original ecs.conf file for the present the
# PClanIntf0 variable and update servers.conf if appropriate.
#
# If PClanIntf0 not present, exit because there is nothing to do.
# If PClanIntf0 present, then
#   Get PE info based on the PClanIntf0 info.
#   Remove the PClanIntf0 and PEInterface variable from ecs.conf
#   If this is a Duplex Main server, then
#     Return 0, don't update servers.conf for Duplex Main servers.
#   Update the servers.conf file with the PE information if necessary.
#   Necessary if:
#     1. There is an entry for PE but doesn't match PClanIntf0 info.
#     2. There are no PE entries in servers.conf.
#        a. Simplex server, create PE entry from PClanIntf0 info.
#        b. Duplex ESS, if same as Customer LAN, use that info to
#           creates entries.  If not, use PClanIntf0 info to create
#           PE entry for this server.
#
############################################################################
sub pe_check($)
{
	my ($ECS_TAR) = @_;

	#
	# Paths used by the module.
	#
	my $ECS_OFF = "/etc/opt/ecs/ecs.conf";
	my $ECS_WORK = "/etc/opt/ecs/ecs.conf.working";
	my $SERVERS_CONF = "/etc/opt/ecs/servers.conf";

	my $eth_pe;		# Ethernet for PE, based on PClanIntf0
	my $dup;		# Duplication config. for this server
	my $essconf;		# ESS configuration for this server
	my $eth;		# Ethernet from lanconfig for PClanIntf0
	my $ip;			# IP Address from lanconfig
	my $dgw;		# Default Gateway from lanconfig
	my $mask;		# Mask from lanconfig
	my $ena;		# Enabled flag from lanconfig (not used)
	my $eth_no;		# Ethernet number
	my $host;		# Host name
	my $hostnum;		# Host/Server number
	my %file;		# File
	my %res;		# Res
	my $o_fh;		# Original File Handle
	my $d_fh;		# Dirty File Handle
	my $commit_needed;	# Commit needed flag
	my @fields;		# Fields for a line of servers.conf
	my @cust1_fields;	# Customer LAN fields for server1
	my @cust2_fields;	# Customer LAN fields for server2
	my $pe_found;		# PE entry found flag
	my $pe_match;		# PE entry match flag
	my $line;		# Line for entry in servers.conf
	my $i;			# Looping variable
	my $cna_eth;		# CNA's Eth device number
	my $cnb_eth;		# CNB's Eth device number
	my $cnc_eth;		# CNC's Eth device number
	my $cust_eth;		# Customer's Eth device number

	#
	# Get the value of the "PClanIntf0" variable from the original tar
	# version of the ecs.conf file.
	#
	$eth_pe = `/bin/awk '\$1 == "PClanIntf0" {print \$2}' $ECS_TAR`;
	my $rc = $?;
	if ($rc != 0)
	{
		log_err "pe_check: awk failed for file: $ECS_TAR: $rc.";
		return(1);
	}
	chomp($eth_pe);

	#
	# If "PClanIntf0" is not present, return 0.  Must be restoring
	# from a version of the ecs.conf file where transition from
	# using the "PClanIntf0" variable to using the "pe" entry or
	# entries in servers.conf.
	#
	if ( ! $eth_pe )
	{
		log_err "pe_check: PClanIntf0 not present, nothing to do.";
		return(0);
	}

	#
	# Copy the official version of ecs.conf to a working copy.
	# Remove the "PClanIntf0" and "PEInterface" variables from the
	# working copy and then copy the working copy back to the
	# official version.
	#
	`/bin/cp -p $ECS_OFF $ECS_WORK`;
	`/bin/sed -i -e '/^PClanIntf0[	 ].*/d' $ECS_WORK`;
	`/bin/sed -i -e '/^PEInterface[	 ].*/d' $ECS_WORK`;
	`/bin/cp -p $ECS_WORK $ECS_OFF`;
	`/bin/rm -f $ECS_WORK`;

	chomp ($host = `/bin/hostname`);

	#
	# Open the servers.conf using the fileop software for file integrity.
	#
	%file = ($SERVERS_CONF => CreateOpenInfo(O_RDWR, 0, LOCK_NOCOPY));
	
	if (!OpenMul(\%file, \%res))
	{
		log_err "pe_check: OpenMul failed for file " .
			"$SERVERS_CONF, error $!";
		return(1);
	}

	#
	# We'll read the current contents of the servers.conf file using
	# the filehandle in $o_fh and write the modified contents to the
	# dirty file using the filehandle in $d_fh.
	#
	$o_fh = $res{$SERVERS_CONF}->orig_fh();
	$d_fh = $res{$SERVERS_CONF}->dirty_fh();

	#
	# We only commit this file if we change its contents.
	# Assume initially that this is not the case.
	#
	$commit_needed = 0;
	$pe_found = 0;
	$pe_match = 0;

	#
	# Loop though the file looking for Customer LAN and/or PE
	# entries.
	#
	while (<$o_fh>)
	{
		#
		# Skip the comment and blank lines.
		#
		if (/^\s*(#.*)?$/)
		{
			next;
		}

		chomp;
		@fields = split /\s+/;	# split line on spaces

		#
		# If this is a Customer LAN entry, then save the
		# the fields for use later, set the server ordinal
		# number, and increment the number of Customer LAN
		# entries.
		#
		if ($fields[0] =~ /^server/)
		{
			if ($fields[0] =~ /1/)
			{
				@cust1_fields = @fields;
			}
			else
			{
				@cust2_fields = @fields;
			}

			#
			# If this Customer LAN entry matches the host
			# name, then extract the server ordinal number
			# from the first field.
			#
			if ("$fields[2]" eq "$host")
			{
				($fields[0] =~ /^server(\d+)$/)
					and $hostnum = $1;
			}

			$cust_eth = $fields[1];
			next;
		}

		#
		# If this is a Processor Ethernet entry, then increment
		# the number of PE entires.
		# 
		if ($fields[0] =~ /^pe/)
		{
			#
			# Check for a match.
			#
			if (("$fields[1]" eq "$eth_no")	&&
			    ("$fields[3]" eq "$ip")	&&
			    ("$fields[4]" eq "$mask")	&&
			    ("$fields[5]" eq "$dgw"))
			{
				$pe_match = 1;
			}
			next;
		}

		if ($fields[0] =~ /^cna/)
		{
			#
			# Save the ethernet device associated with CNA.
			#
			$cna_eth = $fields[1];
			next;
		}

		if ($fields[0] =~ /^cnb/)
		{
			#
			# Save the ethernet device associated with CNB.
			#
			$cnb_eth = $fields[1];
			next;
		}

		if ($fields[0] =~ /^cnc/)
		{
			#
			# Save the ethernet device associated with CNC.
			#
			$cnc_eth = $fields[1];
			next;
		}
	}

	#
	# Check configuration.  If Duplex Main server, then check if
	# a CNC entry needs to be added to the servers.conf file.
	#
	$dup = `/bin/awk '\$1 == "ServerDuplication" {print \$2}' $ECS_TAR`;
	chomp($dup);
	if ($dup !~ /^no$/i)
	{
		$essconf = `/bin/awk '\$1 == "essconfig" {print \$2}' $ECS_TAR`;
		chomp($essconf);
		#
		# A value not equal to "ess", then this is a Main Server.
		#
		if ("$essconf" ne "ess")
		
		{
			#
			# Duplex Main server, check if any of the
			# Control Networks (A, B, or C) are on the
			# Ethernet device as the Customer LAN.
			# If so, then there is nothing to do.
			# Otherwise, determine if a CNC entry
			# needs to be created.
			#
			if (("$cna_eth" eq "$cust_eth") ||
			    ("$cnb_eth" eq "$cust_eth") ||
			    ("$cnc_eth" eq "$cust_eth"))
			{
				log_err "pe_check: Dup Main, nothing to do.";

				if (!AbortMul(\%res))
				{
					log_err "pe_check: AbortMul" .
						" failed for file " .
                                                "$SERVERS_CONF, err $!.\n";
				}
				return(0);
			}

			#
			# Check for IPSI use the Customer LAN
			# Ethernet device.
			#
			open (GREP_CMD, "/bin/grep ipsi /etc/hosts |") ||
			do
			{
				log_err "pe_check: Couldn't grep " .
                                        "/etc/hosts: $!.\n";

				if (!AbortMul(\%res))
				{
					log_err "pe_check: AbortMul" .
						" failed for file " .
                                                "$SERVERS_CONF, err $!.\n";
				}
				return(1);
			};

			my $ipsiOnCustLAN = 0;
			while (<GREP_CMD>)
			{
				my ($ip_addr, $ipsi_name) = split('\s+', $_);
				`/sbin/ip route get $ip_addr 2>/dev/null | /bin/grep "eth$cust_eth" > /dev/null`;
				if ($? == 0)
				{
					#
					# Found an IPSI on the Customer LAN.
					#
					$ipsiOnCustLAN = 1;
					last;
				}
			}
			close(GREP_CMD);

			#
			# Found an IPSI on the Customer LAN, but no CNx
			# entry for that ethernet device, so create a
			# CNC entry in servers.conf.
			#
			if ($ipsiOnCustLAN == 1)
			{
				#
				# Set @fields based on the host number.
				#
				if ($hostnum == 1)
				{
					@fields = @cust1_fields;
				}
				else
				{
					@fields = @cust2_fields;
				}

				#
				# Reset the file handle to the
				# beginning of the file. 
				#
				seek ($o_fh, 0, 0);

				#
				# Read each line from servers.conf and
				# add them to the dirty file.
				#
				while (<$o_fh>)
				{
					print $d_fh $_;
				}

				#
				# Add CNC entry to the end of the
				# servers.conf dirty file.
				#
				print $d_fh "\n";
				print $d_fh "cnc${hostnum}" .
					"       ${fields[1]}" .
					"       ${fields[2]}" .
					"       ${fields[3]}" .
					"       ${fields[4]}" .
					"       ${fields[5]}" .
					"       ${fields[6]}" .
					"       ${fields[7]}" .
					"       ${fields[8]}\n";

				log_err "pe_check: Dup Main: added CNC entry.";

				if (!CommitMul(\%res))
				{
					log_err "pe_check: CommitMul" .
						" failed for file " . 
						"$SERVERS_CONF, err $!.";
					AbortMul(\%res);
					return(1);
				}
				return(0);
			}

			log_err "pe_check: Dup Main: No need to add CNC entry.";
			if (!AbortMul(\%res))
			{
				log_err "pe_check: AbortMul" .
					" failed for file " .
					"$SERVERS_CONF, err $!.\n";
			}
			return(0);
		}
	}

	#
	# Get the LAN configuration for this Ethernet Device.
	#
	open (LANCON, "/opt/ecs/sbin/lanconfig -q -d $eth_pe -W |") ||
	do
	{
		log_err "pe_check: lanconfig for $eth_pe failed: $!.";

		if (!AbortMul(\%res))
		{
			log_err "pe_check: AbortMul" .
				" failed for file " .
				"$SERVERS_CONF, err $!.\n";
		}
		return(1);
	};

	#
	# We expect one line of results or no results if $eth_pe is "unset".
	#
	while (<LANCON>)
	{
		chomp;
		($eth, $ip, $dgw, $mask, $ena) = split /\s+/;
		last;
	}
	close(LANCON);

	#
	# Check if we got lanconfig info. If no data or bad data from a
	# error or usage statement, return an error.
	#
        if ($eth !~ /^eth/)
	{
		log_err "pe_check: no data from lanconfig for $eth_pe.";

		if (!AbortMul(\%res))
		{
			log_err "pe_check: AbortMul" .
				" failed for file " .
				"$SERVERS_CONF, err $!.\n";
		}
		return(1);
	}

	#
	# The lanconfig command returns "none" instead of "NA" which 
	# the servers.conf file excepts.
	#
	if ("$dgw" eq "none")
	{
		$dgw = "NA";
	}

	#
	# Get the Ethernet number and host name.
	#
	$eth_no = $eth_pe;
        $eth_no =~ s/eth([0-9]+\.?[0-9]*)$/$1/;
        $eth_no =~ s/0+/0/; # collapse multiple zeros into one zero

	#
	# If a PE match has been found, then abort file transaction
	# and return success, because there is nothing to update.
	#
	if ($pe_match == 1)
	{
		log_err "pe_check: PE entry already present.";

		if (!AbortMul(\%res))
		{
			log_err "pe_check: AbortMul failed" .
				" for file $SERVERS_CONF, err $!\n";
		}
		return(0);
	}

	#
	# Reset the file handle to the beginning of the file.
	#
	seek ($o_fh, 0, 0);

	#
	# Read each line from servers.conf.
	#
	while (<$o_fh>)
	{
		#
		# Add the comments and blank lines to the dirty file
		# and skip to the next line.
		#
		if (/^\s*(#.*)?$/)
		{
			print $d_fh $_;
			next;
		}

		chomp;
		@fields = split /\s+/;	# split line on spaces

		#
		# The format of the line should be:
		#
		# keywd  eth  name  ip  mask  gateway  get  set  id.
		#
		#
		# If this is the PE entry for this server, then
		# write the updated fields to the file.
		#
		if (($fields[0] =~ /^pe/) &&
		       ($fields[0] =~ /$hostnum/))
		{
			$pe_found = 1;
			$commit_needed = 1;

			$fields[1] = $eth_no;
			$fields[3] = $ip;
			$fields[4] = $mask;
			$fields[5] = $dgw;

			#
			# If the PE's Ethernet device is the same
			# as the customer's, then the server ID
			# field should be the corresponding customer
			# server ID, else it should be NA.
			#
			if ("$cust1_fields[1]" eq "$eth_no")
			{
				$fields[8] = (($hostnum == 1) ?
					$cust1_fields[8] :
					$cust2_fields[8]);
			}
			else
			{
				$fields[8] = "NA";
			}

			$line = "";
			for ($i = 0; $i <= $#fields; $i++)
			{
				$line = "$line" . $fields[$i];
				if ($i < $#fields)
				{
					$line = "$line" . "	";
				}
			}
			print $d_fh $line, "\n";

			log_err "pe_check: Simplex: updating PE entry.";
			next;
		}

		print $d_fh $_, "\n";
	}

	#
	# If we didn't already update a PE entry, then append the
	# appropriate entry or entries to the file.
	#
	if ( ! $pe_found)
	{
		$commit_needed = 1;

		#
		# Print two blank lines and a Processor Ethernet comment.
		#
		print $d_fh "\n\n";
		print $d_fh "# Processor Ethernet\n";

		#
		# If this is a Simplex server, else this must be a
		# Duplex ESS server, because the program returns
		# early if it was a Duplex Main server.
		#
		if ($dup =~ /^no$/i)
		{
			log_err "pe_check: Simplex: adding PE entry.";

			#
			# Create the line and print it.
			#
			$line = "pe1	${eth_no}	${host}-pe" .
				"	${ip}	${mask}	${dgw}" .
				"	NA	NA	";

			#
			# If the PE's Ethernet device is the same
			# as the customer's, then the server ID
			# field should be the customer server ID,
			# else it should be NA.
			#
			if ("$cust1_fields[1]" eq "$eth_no")
			{
				$line = "$line" . "${cust1_fields[8]}\n";
			}
			else
			{
				$line = "$line" . "NA\n";
			}

			print $d_fh $line;
		}
		else
		{
			#
			# Set @fields based on the host number.
			#
			if ($hostnum == 1)
			{
				@fields = @cust1_fields;
			}
			else
			{
				@fields = @cust2_fields;
			}

			#
			# If the Customer LAN for this server matches
			# the PE values, then generate both lines based
			# on the Customer LAN values, else generate the
			# PE line for this server.
			#
			if (("$fields[1]" eq "$eth_no")	&&
			    ("$fields[3]" eq "$ip")	&&
			    ("$fields[4]" eq "$mask")	&&
			    ("$fields[5]" eq "$dgw"))
			{
				log_err "pe_check: Dup ESS: adding PE entries.";

				print $d_fh "pe1	${cust1_fields[1]}" .
					"	${cust1_fields[2]}-pe" .
					"	${cust1_fields[3]}" .
					"	${cust1_fields[4]}" .
					"	${cust1_fields[5]}" .
					"	${cust1_fields[6]}" .
					"	${cust1_fields[7]}" .
					"	${cust1_fields[8]}\n";

				print $d_fh "pe2	${cust2_fields[1]}" .
					"	${cust2_fields[2]}-pe" .
					"	${cust2_fields[3]}" .
					"	${cust2_fields[4]}" .
					"	${cust2_fields[5]}" .
					"	${cust2_fields[6]}" .
					"	${cust2_fields[7]}" .
					"	${cust2_fields[8]}\n";
			}
			else
			{
				log_err "pe_check: Dup ESS: adding PE entry.";
				$line = "pe${hostnum}	${eth_no}" .
					"	${host}-pe	${ip}" .
					"	${mask}	${dgw}	NA" .
					"	NA	NA\n";

				print $d_fh $line;
			}
		}
	}

	#
	# Commit the dirty file if needed.
	#
	if ($commit_needed)
	{
		if (!CommitMul(\%res))
		{
			log_err "pe_check: CommitMul failed for" .
				" file $SERVERS_CONF, err $!";
			AbortMul(\%res);
			return(1);
		}
	}
	else
	{
		if (!AbortMul(\%res))
		{
			log_err "pe_check: AbortMul failed for" .
				" file $SERVERS_CONF, err $!";
			return(1);
		}
	}
	return(0);
}



sub file_cleanup
{
	#######################################################################
	# replace lacfile with original lacfile from current version; 
	#######################################################################
	$replace_lacfile= "/etc/lacfile";
	$latest_lacfile="/etc/lacfile.latestversion";
	if (-s $latest_lacfile)
	{
		if (system("cp -p $latest_lacfile $replace_lacfile"))
		{
			log_err "unable to restore lacfile - may cause "
			  . "system function problem";
			 return(5);
		}
		unlink $latest_lacfile;
	} 
	else
	{
		unlink $replace_lacfile;
	}
	#######################################################################
	#  remove any "latestversion files in /etc/sysconfig/network-scripts
	#   and use the ones from the restore image
	#######################################################################
	@file_network=`ls /etc/sysconfig/network-scripts/ifcfg-eth*.latestversion 2>/dev/null`;
	map {chomp $_} @file_network;

	foreach $netwk_file (@file_network)
	{
		if (-s $netwk_file)
		{	
			unlink $netwk_file;
		}
	}

	#######################################################################
	#  restore current version of backup files
	#######################################################################
	@backupset_files=`ls /etc/opt/ecs/backup/*.conf 2>/dev/null`;
	map {chomp $_} @backupset_files;


	#######################################################################
	# these files will be totally removed from tar image
	# using the following rules; 
	#	1. if they existed prior to restore (i.e. *.latestversion) then they 
	#      will be set to the default file on system prior to restore
	#   2. if they didn't exist prior to resotre (i.e. *.latestversion doesn't 
	#		exist), then file will be removed from system.  Indicates that 
	#       file nolonger valid
	#	NOTE:  These files will remain at the "tar" version content 
	#		"/etc/opt/ecs/ip_fw_clan.conf",
	#		"/etc/opt/ecs/snmp_m.conf",
	#######################################################################
	@remove_from_system=( "/etc/inetd.conf", "/etc/pwdb.conf",
		"/root/.rhosts", "/etc/host.conf", "/etc/ld.so.conf",
		"/etc/logrotate.conf","/etc/ltrace.conf",
		"/etc/httpd/conf/ssl.crt/server.crt",
		"/etc/httpd/conf/ssl.key/server.key",
		"/etc/nsswitch.conf",
		"/etc/httpd/conf/ssl.key/server.pem",
		);

	push (@remove_from_system, @backupset_files);
	
	
	#######################################################################
	# remove file totally from system            
	#######################################################################
	foreach $rmv_file (@remove_from_system)
	{
		# copy latest version back to system version; if it exists
		$latest_rmv_file= $rmv_file.'.latestversion';
		if (-s $latest_rmv_file)
		{
			if (system("cp -p $latest_rmv_file $rmv_file"))
			{
				log_err "unable to replace tar version of "
				  . "file $rmv_file - may cause system function problem";
				return(5);
			}
		    	################################################################
			# remove the latest version backup (can ignore error if 
			#  unable to remove backup; doesn't affect system function)
			#################################################################
			unlink $latest_rmv_file;
		}
		#######################################################################
		# only tar version of file exists; remove from system
		# *****************NOT SURE IF WE WANT TO ACTUALLY REMOVE FILE FROM 
	        # **********SYSTEM IF IT WASN'T ON SYSTEM PRIOR TO RESTORE; LEAVE
        	# ********** ON SYSTEM FOR NOW.   4/14/06
		#######################################################################
		#else
		#{
			#	unlink $rmv_file;
		#}

	}
  
	return 0;
}

#########################################################################
#  restore_pwd - sets access files back to their value before the restore
#    occurred; done to avoid lockout on system
#########################################################################
sub restore_pwd {
    system("mv /etc/passwd.latestversion /etc/passwd");
    system("mv /etc/shadow.latestversion /etc/shadow");
    system("mv /etc/group.latestversion /etc/group");
}




########################################################
# Set permissions on crond files and restart cron
# based on second argument
# Note: cron 4.1 requires no executable permission and
# and only owner can have write permission
# for files in /etc/cron.d
########################################################
sub crond_file_check( $ $ ) # ARGS( STRING caller name for logging,
# boolean: restart crond if true, else no restart )
{
    use strict; # note: local to this function

    my $cmd = shift;
    my $restart_cron = shift;

    log_info "Checking cron.d permissions in /etc/cron.d";
    # enforce permissions required by cron.d
    for my $file (</etc/cron.d/*.definity /etc/crontab>)
    {
        ! system('chmod', 'ugo-x', $file) 
	  or log_err "Failure setting permissions on file: $file";
        ! system('chmod', 'go-w', $file) 
	  or log_err "Failure setting permissions on file: $file";
        ! system('chown', 'root:root', $file) 
	  or log_err "Failure setting ownership of file: $file";
    }
    # restart cron
    if ( $restart_cron )
    {
        ! system('service', 'crond', 'restart') 
	  or log_err "Failure restarting crond service";
    }
}


##############################################
#
# Update old scheduled backup crontab 
# file (/etc/cron.d/webbackup*definity)
# to 4.1 "secure" format -- for web
# compatibility and increased security
#
# - logs update failure to syslog
#
# ARGS 1) full path of crontab backup job file
#
# RETURNS - 0 success else non-zero for failure
##############################################
sub update_sched_bkup($)
{
	use strict;
	my $file = shift;
	my $handle;
	my $secure_file;
	my $anonymous_ftp = 0;	

	if( ! -e $file )
	{
		return 1;
	}
	else
	{
		open ($handle, '<', $file) or return 2;
		my $line = <$handle>;
		close $handle;
		($secure_file) = $line =~ /\s+--secure_file\s+(\S+)/ ;

		if( $secure_file )
		{
			# file does not need update -- already
			# using secure_file option
			return 0;
		}
		else
		{
			# we have to update this file
			# to use --secure_file option
			my ($pass, $phrase);

			# note: password/phrase can have spaces
			($pass) = 
	  		  $line =~ /\s+(?:ftp|sftp|scp):\/\/\S+:'(.+)'@/;
	
			# check for anonymous ftp where pass will be ""
			if( ! defined($pass) )
			{
				if( $line =~ 
					/\s+ftp:\/\/\'anonymous\':@/ 
					)
				{
					$anonymous_ftp = 1;
					$pass = "";
					$line =~ 
					  s/(\s+ftp:\/\/\'anonymous\'):@/$1@/;
				}
				
			}			

			# remember that passphrase can have space within it
			($phrase) = 
				$line =~ /\s+-k\s+\'(.+)\'/;

			if( ! (defined($phrase) || defined($pass)) )
			{
				# no need to update file
				return $secure_file;
			}
			else
			{
				# have pass/key to encrypt
				my $tstamp = join '', localtime();
				my $dir = 
					'/etc/opt/ecs/backup/backup_sf';
				$secure_file = 
					$dir . "/${tstamp}.bsf"; 
				while(  -e $secure_file )
				{
					# make sure we dont clobber 
					# existing file
					$tstamp = join '', localtime();
					$secure_file = 
						$dir . "/${tstamp}.bsf"; 
					
				}
				
				# put password, pasphrase into
				# obfuscated file
    				# - don't need secure file if
				# no passphrase and anonymous ftp in use
				if( ! ($anonymous_ftp &&
					!defined($phrase)) )
				{
					open ($handle,
					    '| /opt/ecs/sbin/bkup_pass ' .
					    ' -e ' .
					    (defined($pass) ? ' -p ' : '') .
					    (defined($phrase) ? ' -k ' : '') .
					    ' -o ' .
					    $secure_file
					    ) or return 3;
					if( defined($pass) )
					{
						print $handle "$pass\n" or
						return 4;
					}
					if( defined($phrase) )
					{
						print $handle "$phrase\n" or
						return 5;
					}
					close $handle or return 6;
				}
				# update crontab file
				# make backup copy in case something fails
				! system('cp',$file,"${file}.orig")
					or return 7;

				# now, the update
				do
				{
					open  ($handle, '>', $file) or 
						last;

					# remove password/passphrase from line
					$line =~
					  s/\s+-k\s+\'.+\'\s+/ -k / 
						if defined($phrase);

					$line =~ 
				s/(\s+(:?scp|sftp|ftp):\/\/\S+):\'.+\'/$1/
						if defined($pass);
				
					# use the --secure_file option
					# - don't need secure file if
					# no passphrase and anonymous ftp in 
					# use
					if( ! ($anonymous_ftp && 
						!defined($phrase)) )
					{
						$line =~
				  s/ -b / -b --secure_file $secure_file / 
							or last;
					}
					print $handle "$line\n" or last;
					close $handle or last;
					system('rm',"${file}.orig");
					return 0;
				
				} while(0);
			
				# handle failures that require
				# restoring original crontab file
				system('cp',"${file}.orig",$file);
				log_err "failed to update scheduled backup" .
					" crontab file [$file] to new " .
					" format ";
				return 8;
			}
		}
	}
}

###############################################################################
#
# Log command execution to command history
# 	Log to STDERR so that upgrade process will capture this output
#
###############################################################################
sub log_cmd()
{
    system('logger', '-s', '-p', 'local0.info',
      '-t', "BACKUP", $FindBin::Script);
}

###############################################################################
#
# Log ERRORs to system log and STDERR
# 	Log to STDERR so that upgrade process will capture this output
#
###############################################################################
sub log_err( @ )
{
    system('logger', '-s', '-p', 'user.err',
      '-t', "BACKUP: $FindBin::Script [ERR]", @_);
}


###############################################################################
#
# Log informational messages to system log and STDERR
# 	Log to STDERR so that upgrade process will capture this output
#
###############################################################################
sub log_info( @ )
{
    system('logger', '-s', '-p', 'user.info',
      '-t', "BACKUP: $FindBin::Script", @_);
}

###############################################################################
#
# Description
#   checks if server is duplex
# Parameter
# (1) server duplex mode "yes", "software", "no", ""
# Return values
#   0  server mode is simplex
#   1  server mode is software duplex
#   2  server mode is hardware duplex
#   defined in duplex_mode
#
###############################################################################
sub is_duplex ($)
{
	my ($srvr_duplex) = @_;
	if(($srvr_duplex eq "") || ($srvr_duplex eq "no"))
	{
		return $duplex_mode{simplex};
	}
	elsif ($srvr_duplex eq "software")
	{
		return $duplex_mode{sw_dup};
	}
	elsif ($srvr_duplex eq "yes")
	{
		return $duplex_mode{hw_dup};
	}
}

sub is_migration_allowed($$$$)
{
	# Description
	#   This sub routine checks the valid migration paths from the first
	#   server type argument to the second.
	# Arguments
	#   (1) srvr_tar: The server type in the backup/restore tar archive
	#   (2) srvr_cur: The server type of the current machine
	#   (3) duplex_tar: The server duplex mode in the backup/restore tar archive
	#   (4) duplex_cur: The server duplex mode of the current machine
	# Return values
	#   1: The migration from (1) to (2) is allowed
	#      The server types are different
	#   2: The migration from (1) to (2) is allowed
	#      The server types are equal
	#   0: The migration from (1) to (2) is NOT allowed

	my $srvr_tar = shift;
	my $srvr_cur = shift;
	my $duplex_tar = shift;
	my $duplex_cur = shift;

	if(
	# 8300 server family
	   # 8300A/B (icc) to 8300C (8300c)
	   (($srvr_tar eq "icc") && ($srvr_cur eq "s8300c")) ||

	   # 8300A/B (icc) or S8300C to 8300D (8300d)
	   ((($srvr_tar eq "icc")       ||
	     ($srvr_tar eq "s8300c")) && ($srvr_cur eq "s8300d")) ||

	# 8500 server family
	   # 8500A (ibmx305) to 8500B (ibmx306)
	   (($srvr_tar eq "ibmx305") && ($srvr_cur eq "ibmx306")) ||

	   # 8500A (ibmx305) or 8500B (ibmx306) or 8500C (ibmx306m) to
	   # 8510 (dell1950)
	   ((($srvr_tar eq "ibmx305")   ||
	     ($srvr_tar eq "ibmx306")   ||
	     ($srvr_tar eq "ibmx306m")) && ($srvr_cur eq "dell1950")) ||

	# 8700 server family
	   # 8700 (isp2100) to
	   # 8710 (dl380g3) or 8720 (dl385g1) or 8730 (dl385g2)
	   (($srvr_tar eq "isp2100") && (($srvr_cur eq "dl380g3")   ||
	                                 ($srvr_cur eq "dl385g1")   ||
                                         ($srvr_cur eq "dl385g2"))) ||

	   # 8710 (dl380g3) to
	   # 8720 (dl385g1) or 8730 (dl385g2)
	   (($srvr_tar eq "dl380g3") && (($srvr_cur eq "dl385g1")   ||
	                                 ($srvr_cur eq "dl385g2"))) ||

	   # 8720 (dl385g1) to 8730 (dl385g2)
	   (($srvr_tar eq "dl385g1") && ($srvr_cur eq "dl385g2")) ||

	# Virtual servers
	   # xen to
	   # 8730 (dl385g2) or 8510 (dell1950) or (ibmx3550) or (dl360g7)
	   (($srvr_tar eq "xen") &&
	   	(($srvr_cur eq "dl385g2")    ||
	         ($srvr_cur eq "dell1950")   ||
		 ((($srvr_cur eq "ibmx3550") || ($srvr_cur eq "dl360g7")) &&
		  (is_duplex($duplex_cur) != $duplex_mode{hw_dup})))) ||

	   # 8500B (ibmx306) or 8500C (ibmx306m) or (ibmx3550) or (dl360g7) to
	   # xen
	   ((($srvr_tar eq "ibmx306")   ||
	     ($srvr_tar eq "ibmx306m")  ||
	     ($srvr_tar eq "dell1950")  ||
	     ((($srvr_tar eq "ibmx3550") || ($srvr_tar eq "dl360g7")) &&
	      (is_duplex($duplex_tar) != $duplex_mode{hw_dup}))) &&
	    ($srvr_cur eq "xen")) ||

	# S8800 server family (successor of s8500 and s8700 family)
	   # 8500A (ibmx305) or 8500B (ibmx306) or 8500C (ibmx306m) or
	   # 8510 (dell1950) to S8800 (ibmx3550) if not duplex
	   ((($srvr_tar eq "ibmx305")   ||
	     ($srvr_tar eq "ibmx306")   ||
	     ($srvr_tar eq "ibmx306m")  ||
	     ($srvr_tar eq "dell1950")) &&
	    (($srvr_cur eq "ibmx3550") || ($srvr_cur eq "dl360g7")) &&
	    (is_duplex($duplex_cur) == $duplex_mode{simplex})) ||

	# S8800 server family (successor of s8500 and s8700 family)
	   # 8700 (isp2100) or 8710 (dl380g3) or 8720 (dl385g1) or
	   # 8730 (dl385g2) to S8800 (ibmx3550) if duplex
	   ((($srvr_tar eq "isp2100")  ||
	     ($srvr_tar eq "dl380g3")  ||
	     ($srvr_tar eq "dl385g1")  ||
	     ($srvr_tar eq "dl385g2")) &&
	    (($srvr_cur eq "ibmx3550") || ($srvr_cur eq "dl360g7")) &&
	    (is_duplex($duplex_cur) == $duplex_mode{sw_dup})) ||

	# S8800 to HP_DL360_G7
	   (($srvr_tar eq "ibmx3550") && ($srvr_cur eq "dl360g7") &&
	    (is_duplex($duplex_tar)) == (is_duplex($duplex_cur)))

	)
	{
		# migration is allowed, server types are different
		return 1;
	}
	elsif(($srvr_tar eq $srvr_cur) && 
	      ($srvr_tar ne "ibmx3550") && ($srvr_tar ne "dl360g7"))
	{
		# migration is allowed, server types are equal
		return 2;
	}
	elsif(($srvr_tar eq $srvr_cur) && 
	      (($srvr_tar eq "ibmx3550") || ($srvr_tar eq "dl360g7")) &&
	      (is_duplex($duplex_cur) == is_duplex($duplex_tar)) &&
	      (is_duplex($duplex_cur) != $duplex_mode{hw_dup}))
	{
		# migration is allowed, server modes (simplex, duplex) are equal
		# and server mode on the current system is not hardware dup
		return 2;
	}

	# migration is NOT allowed
	return 0;
}


#
# NAME: check_disk_root
#
# WHAT: check to see if RAMDISK is enabled or not.
#       returns a blank string if not or /diskroot if it is enabled
#
# SPECICAL CONSIDERATIONS:
#       none
#
sub check_disk_root()
{
	my $ProcHandler;
	my $diskRoot = '';

	open ($ProcHandler, "/bin/df | ") ||
	do
	{
		print STDERR "Failed to run /bin/df\n";
		exit (1);
	};

	while (<$ProcHandler>)
	{
		/\/dev\/ramdisk / &&
		do
		{
			$diskRoot = "/diskroot";
			last;
		};
	}

	close ($ProcHandler);

	return $diskRoot;
}

# don't remove this  
1;

