#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2006,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 
# @(#)25   1.8   src/csm/softmaint/cmds/sms_local.perl, csm.softmaint, csm_rfish, rfishs001b 11/10/06 00:24:28
#
# This routine replaces smslocal as of 1.6.0.0 to support minmanaged nodes
# It had to be renamed to move to csm.core which was required so it
# could be copied into /csminstall/csm for minmanaged nodes
# Also a new message map file had to be created for the move to core

use Getopt::Std;

BEGIN
{
	use File::Basename;
	($::Bin) = dirname($0);    # get current directory
	if (-e "$::Bin/csmSMSlocal.sms_local.map") # working from mounted dir
	{
	  $::csmpm            = $::Bin;
	  $::MSGMAPPATH       = $::Bin;
	  $NodeUtils::MSGMAPPATH = $::MSGMAPPATH;
    } else {  # in install path
	   $::csmpm = $ENV{'CSM_PM'} ? $ENV{'CSM_PM'} : '/opt/csm/pm';
       $::MSGMAPPATH = $ENV{'CSM_MSGMAPS'} ? $ENV{'CSM_MSGMAPS'} : '/opt/csm/msgmaps';
	  $NodeUtils::MSGMAPPATH = $::MSGMAPPATH;
	}

}    #for development use
use lib $::csmpm;
use NodeUtils;
use ArchiveUtils;
use ServerUtils;
use CSMDefs;
use strict;
use locale;

$::MSGCAT     = 'csmSMSlocal.cat';
$::MSGSET     = 'sms_local';
$ENV{'CT_MANAGEMENT_SCOPE'} = 1;

# get the definitions we need for this command
my %OSDefs = ServerUtils->get_OSDefs($::PLTFRM);

# the configinfo file was created either by csmprereboot during a
#    full install or by updatenode.client during a csm-only install.
$::CFGINFOFILE = "/opt/csm/install/configinfo";

$::GLOBAL_EXIT = 0;
# build command line input
my @command_line = ();
@command_line   = @ARGV;
my $command_line = $0 . " " . join(" ", @command_line);

MessageUtils->start_logging("/var/log/csm/sms_local.log");
MessageUtils->message('LV', 'IMsgCmd', $command_line);
#check usage
if (!getopts('hnu:r:i:p:EStd:vV')) { &usage; exit(1); }
if ($::opt_h) { undef $::opt_h; &usage; exit(0); }
if ($::opt_u) { $main::UPDATE_DIR = $::opt_u; undef $::opt_u; }
if ($::opt_r) { $main::RPM_DIR    = $::opt_r; undef $::opt_r; }

# if($::opt_i){ $main::INSTALL_RPMS = $::opt_i; undef $::opt_i; }
if ($::opt_E)
{
	$main::ERASE_RPMS = $::opt_E;
	@main::E_RPMS     = @ARGV;
	undef $::opt_E;
}
if ($::opt_S) { $main::UPDATENODE_DSH = 1;        undef $::opt_S; }
if ($::opt_t) { $main::TEST           = $::opt_t; undef $::opt_t; }
if ($::opt_d) { $main::BASE_DIR       = $::opt_d; undef $::opt_d; }
if ($::opt_n) { $main::noinsdeps      = 1;        undef $::opt_n; }
if ($::opt_v || $::opt_V) { $::VERBOSE = 1; }
if ($::opt_i)
{
	$main::INSTALL_RPMS = $::opt_i;
	undef $::opt_i;
}
if ($::opt_p)
{
	$main::PACKAGES = $::opt_p;
	undef $::opt_p;
}
if ($main::BASE_DIR)
{
	if (!$main::RPM_DIR)
	{
		$main::RPM_DIR = "$main::BASE_DIR/RPMS/";
	}
	if (!$main::UPDATE_DIR)
	{
		$main::UPDATE_DIR = "$main::BASE_DIR/updates/";
	}
	if (!$main::INSTALL_DIR)
	{
		$main::INSTALL_DIR = "$main::BASE_DIR/install/";
	}
}

if ($main::ERASE_RPMS)
{
	foreach my $rpm (@main::E_RPMS)
	{
		&erase($rpm);
	}
	exit;
}
else
{

	my $sl_dir;
	if (&get_node_info != 0)
	{

		# Could not read config_info file.
		MessageUtils->messageFromCat('csmInstall.cat', $::MSGMAPPATH,
									 'csminstall', 'E', 'EMsgNO_Attr_Values');
		$::GLOBAL_EXIT = 1;
		exit;
	}
	if ($main::UPDATENODE_DSH)
	{
		$main::RPM_DIR =
		  ArchiveUtils->getRPMSDir($::ostype, $::osdistr, $::osversion, $::arch,
								   $::servicelevel);
		$main::UPDATE_DIR =
		  ServerUtils->getUpdateDir($::ostype, $::osdistr, $::osversion,
									$::arch, $::servicelevel);

		#todo: get node groups
	}
	elsif ($main::BASE_DIR)
	{
		my ($csm, $nothin);
		($nothin, $csm, $::ostype, $::osdistr, $::osversion, $::arch, $sl_dir) =
		  split "/", $main::BASE_DIR;
	}
	elsif ($main::RPM_DIR)
	{
		my ($csm, $nothin, $dir);
		(
		 $nothin, $csm, $::ostype, $::osdistr, $::osversion, $::arch, $sl_dir,
		 $dir
		)
		  = split "/", $main::RPM_DIR;
	}
	elsif ($main::UPDATE_DIR)
	{
		my ($csm, $nothin, $dir);
		(
		 $nothin, $csm, $::ostype, $::osdistr, $::osversion, $::arch, $sl_dir,
		 $dir
		)
		  = split "/", $main::UPDATE_DIR;
	}

	if ($::osdistr =~ /SLES/)
	{
		if ($sl_dir =~ m/\S+/)
		{
			$::servicelevel = $sl_dir;
		}
	}
	else
	{
		$sl_dir =~ s/$::osdistr//g;
		$sl_dir =~ s/$::osversion\-//g;
		if (   $sl_dir =~ /i386/
			|| $sl_dir =~ /ppc64/
			|| $sl_dir =~ /x86_64/
			|| $sl_dir =~ /ia32e/)
		{
			$::servicelevel = "GA";
		}
		else
		{
			$::servicelevel = $sl_dir;
			chomp $::servicelevel;
		}
	}
	$main::BASE_DIR =
	  ServerUtils->getBaseDir($::ostype, $::osdistr, $::osversion, $::arch,
							  $::servicelevel);
	$main::INSTALL_DIR = "$main::BASE_DIR/install/";

	&fixMountPoint();   #since the mount point has changed to $::CSMCLIENTMNTDIR

	my @dirs     = ($main::UPDATE_DIR, $main::INSTALL_DIR);
	my $notfound = 1;
	my $i        = 1;
	foreach my $dir (@dirs)
	{
		if (!-d $dir || (!-f glob("$dir/*.rpm") && !-f glob("$dir/*/*.rpm")))
		{
			my (
				$nothin, $var,    $opt,     $csm,
				$mnt,    $ostype, $osdistr, $osversion,
				$arch,   $sl_dir, $end_dir
			   )
			  = split "/", $dir;
			$dir =
			  "/$var/$opt/$csm/$mnt/$ostype/$osdistr/$osversion/$arch/$end_dir";
			if ((-f glob("$dir/*.rpm")) || (-f glob("$dir/*/*.rpm")))
			{
				$notfound = 0;
			}
			if ($i eq 1)
			{
				$main::UPDATE_DIR = $dir;
			}
			else
			{
				$main::INSTALL_DIR = $dir;
			}
		}
		else
		{
			$notfound = 0;
		}
		$i++;
	}
	if ($notfound)
	{
		MessageUtils->message('I', 'IMsgNoUpdated');
		exit;
	}
	&queryAutoupdate();
	&checkConfigFile();

	%main::groups = ();  #all groups that this node is in will be stored in here
	&check_group();

	#checkout config file
	if (!(-e "/var/opt/csm/autoprovides.db"))
	{
		if (-e "$main::RPM_DIR/autoprovide.db")
		{
			NodeUtils->runcmd(
				"/bin/cp $main::RPM_DIR/autoprovide.db /var/opt/csm/autoprovides.db");
		}
		else
		{
			if (ArchiveUtils->checkDistroCopied($main::RPM_DIR))
			{
				unlink("/var/opt/csm/tmp.autoprovides.db");

				#`$::RM -f /var/opt/csm/tmp.autoprovides.db 2>/dev/null`;
				MessageUtils->message('I', 'IMsgCreatingDB');

				# path length has to be reduced,
				# then the issue "argument list too long" will be avoided
				# one link which is much shorter is created
				if (!-d "/tmp")
				{
					NodeUtils->runcmd("/bin/mkdir /tmp", 0);
				}
				my $temp_link = "/tmp/RPM";
				unlink $temp_link;
				symlink $main::RPM_DIR, $temp_link;
				NodeUtils->createAutoupdateDB("$temp_link/*.rpm");
				unlink $temp_link;
			}
			else
			{
				MessageUtils->message('V', 'IMsgNoDistribRPMS');
				$::NO_DB = 1;
			}
		}
	}
	if (!-e "$main::UPDATE_DIR" || !-e "$main::RPM_DIR")
	{
		exit 1;
	}
	my @rpmlist = NodeUtils->runcmd("/bin/rpm -qa", 0);

	if ($main::INSTALL_RPMS)
	{    #install given rpms
		&run_install();
	}
	else
	{
		&install_from_insdir();
		&run_update();
	}
	my $flag        = 0;
	my @new_rpmlist = NodeUtils->runcmd("/bin/rpm -qa", 0);
  COMPARE: foreach my $item (@rpmlist)
	{
		my $newitem = shift @new_rpmlist;
		if ($item ne $newitem)
		{
			$flag = 1;
			last COMPARE;
		}
	}
	if (scalar @new_rpmlist >= 1)
	{
		$flag = 1;
	}
	if ($flag == 1)
	{
		MessageUtils->message('I', 'IMsgRPMUpdated');
	}
	else
	{
		MessageUtils->message('I', 'IMsgNoUpdated');
	}
}

END
{
	MessageUtils->stop_logging();
	if ($::GLOBAL_EXIT > $?)
	{
		$? = $::GLOBAL_EXIT;
	}
	MessageUtils->message('O', 'IMsgSmslocalExit', $?);
}

#return exit code

sub usage { MessageUtils->message('I', 'IMsgSmsNodeUpdateUsage'); }

#check if i'm in any subdirectories that should be checked.
#check the $::CSMCLIENTMNTDIR/csm/var/smsupdate.info for our hostname
sub check_group
{

	
	# if rsct is on the node
	my @hostname;
	if ( -e "/usr/bin/lsrsrc-api") {
 	  @hostname =
	  NodeUtils->runcmd(
	"/usr/bin/lsrsrc-api -i -s IBM.ManagementServer::\"ManagerType='CSM'\"::LocalHostname");
	chomp $hostname[0];
    } else {   # minmanaged node
	   my @thostname = `/bin/hostname 2>&1`;
	   if( ($? >> 8) != 0){
	       MessageUtils->message('E', 'EMsgCommandFailed', "/bin/hostname", "$! $?");
	    } else {
		  chomp($thostname[0]);
		  my ($newhostname, $ip) = NetworkUtils->getHost($thostname[0]);
          $hostname[0]=$newhostname; 
		}
	}
	MessageUtils->message('V', 'IMsgLocalHostName',$hostname[0]);
	if (-e "$::CSMCLIENTMNTDIR/csm/config/sms.info")
	{
		my @group_results =
		  NodeUtils->runcmd(
			   "/bin/grep ^$hostname[0] $::CSMCLIENTMNTDIR/csm/config/sms.info",
			   -1);
		my @groups = split ' ', $group_results[0];
		shift @groups;    #first part is the hostname
		foreach my $g (@groups)
		{
			$main::groups{$g} = 1;
		}
	}
}

sub run_install
{
	MessageUtils->message('I', 'IMsgRunningInstall');
	$main::INSTALL_RPMS =~ s/,/ /g;
	my $autoIns_cmd = "/usr/sbin/autoins ";
	$autoIns_cmd .= "--config /var/opt/csm/autoupdate.conf ";
	(my $rpmfile_basename = $main::INSTALL_RPMS) =~ s:^.*/::g;
	if (($rpmfile_basename =~ /ppc/) && (!($rpmfile_basename =~ /ppc64/)))
	{
		$autoIns_cmd .= "--arch ppc ";
	}
	$autoIns_cmd .= "--updatedir $main::UPDATE_DIR ";
	$autoIns_cmd .= "--rpmdir $main::RPM_DIR ";
	if (!$::NO_DB)
	{
		$autoIns_cmd .= "--database /var/opt/csm/autoprovides.db ";
	}
	else
	{
		$autoIns_cmd .=
		  "--noaddtodb --database /var/opt/csm/tmp.autoprovides.db ";
	}

	#	$autoIns_cmd .= "--addtodb "; #this takes a long time.
	$autoIns_cmd .= "--verbose ";
	if ($main::TEST)
	{
		$autoIns_cmd .= "--test ";
	}
	if ($main::noinsdeps)
	{
		$autoIns_cmd .= "--noresolve ";
	}
	$autoIns_cmd .= "$main::INSTALL_RPMS ";
	MessageUtils->message('V', 'IMsgRUN_SMSLOCAL_CMD', $autoIns_cmd);
	my @results = `$autoIns_cmd 2>&1`;
	chomp(@results);
	my $autoIns_exit = $? >> 8;
	if ($autoIns_exit != 0)
	{
		MessageUtils->message(      'E',          'EMsgCommandFailed',
							  $autoIns_cmd, "$! $autoIns_exit");
		if ($::GLOBAL_EXIT < 2)
		{
			$::GLOBAL_EXIT = 2;
		}
		foreach my $line (@results)
		{
			MessageUtils->message('O', 'IMsgAutoUpdateDetails', $line);
		}
	}
	else
	{
		foreach my $line (@results)
		{
			MessageUtils->message('V', 'IMsgAutoUpdateDetails', $line);
		}
	}
	if ($main::TEST)
	{
		&printTestOutput("Install", @results);
	}

}

#run autoupdate with the given directories
sub run_update
{
	my $run_count = 1;    #need to run twice on some architectures
	my ($last_command, $last_exit);
	MessageUtils->message('I', 'IMsgRunningUpdate');
	my $autoUpd_cmd = "/usr/sbin/autoupd ";

	# $autoUpd_cmd .= "--addtodb "; #this takes a long time.
	$autoUpd_cmd .= "--config /var/opt/csm/autoupdate.conf ";
	$autoUpd_cmd .= "--updatedir $main::UPDATE_DIR ";
	$autoUpd_cmd .= "--rpmdir $main::RPM_DIR ";
	if (!$::NO_DB)
	{
		$autoUpd_cmd .= "--database /var/opt/csm/autoprovides.db ";
	}
	else
	{
		$autoUpd_cmd .=
		  "--noaddtodb --database /var/opt/csm/tmp.autoprovides.db ";
	}
	$autoUpd_cmd .= "--verbose ";
	if ($main::TEST)
	{
		$autoUpd_cmd .= "--test ";
	}
	if ($main::noinsdeps)
	{
		$autoUpd_cmd .= "--noresolve ";
	}
	if ($main::PACKAGES)
	{    #only update these
		(my $rpmfile_basename = $main::PACKAGES) =~ s:^.*/::g;
		if (($rpmfile_basename =~ /ppc/) && (!($rpmfile_basename =~ /ppc64/)))
		{
			$autoUpd_cmd .= "--arch ppc ";
		}
		$main::PACKAGES =~ s/,/ /g;
		$autoUpd_cmd .= "$main::PACKAGES ";
	}
	else
	{
		if ($::arch =~ m/ppc/)
		{ #we need to run the command twice, once with --arch ppc, and once without
			$run_count++;

			#$autoUpd_cmd .= "--arch ppc ";
		}
	}
	while ($run_count > 0)
	{
		MessageUtils->message('V', 'IMsgRUN_SMSLOCAL_CMD', $autoUpd_cmd);
		my @results = `$autoUpd_cmd 2>&1`;
		chomp(@results);
		my $autoUpd_exit = $? >> 8;
		$last_command = $autoUpd_cmd;
		$last_exit    = $autoUpd_exit;
		if ($autoUpd_exit != 0)
		{
			$run_count = 0;    #don't run again if there was a problem
			  # MessageUtils->message('E', 'EMsgCommandFailed', $autoUpd_cmd, "$! $autoUpd_exit");
			if ($::GLOBAL_EXIT < 2)
			{
				$::GLOBAL_EXIT = 2;
			}
			foreach my $line (@results)
			{
				MessageUtils->message('O', 'IMsgAutoUpdateDetails', $line);
			}
		}
		else
		{
			$autoUpd_cmd .= "--arch ppc ";
			foreach my $line (@results)
			{
				MessageUtils->message('V', 'IMsgAutoUpdateDetails', $line);
			}
		}
		if ($main::TEST)
		{
			&printTestOutput("Update", @results);
		}
		$run_count--;
	}

	foreach my $group (sort keys %main::groups)
	{
		if (-e "$main::UPDATE_DIR/$group")
		{
			$run_count   = 1;
			$autoUpd_cmd = "/usr/sbin/autoupd ";

			# $autoUpd_cmd .= "--addtodb "; #this takes a long time.
			$autoUpd_cmd .= "--config /var/opt/csm/autoupdate.conf ";
			$autoUpd_cmd .= "--updatedir $main::UPDATE_DIR/$group ";
			$autoUpd_cmd .= "--rpmdir $main::RPM_DIR ";
			if (!$::NO_DB)
			{
				$autoUpd_cmd .= "--database /var/opt/csm/autoprovides.db ";
			}
			else
			{
				$autoUpd_cmd .=
				  "--noaddtodb --database /var/opt/csm/tmp.autoprovides.db ";
			}
			$autoUpd_cmd .= "--verbose ";
			if ($main::TEST)
			{
				$autoUpd_cmd .= "--test ";
			}
			if ($main::noinsdeps)
			{
				$autoUpd_cmd .= "--noresolve ";
			}
			if ($main::PACKAGES)
			{    #only update these
				(my $rpmfile_basename = $main::PACKAGES) =~ s:^.*/::g;
				if (   ($rpmfile_basename =~ /ppc/)
					&& (!($rpmfile_basename =~ /ppc64/)))
				{
					$autoUpd_cmd .= "--arch ppc ";
				}
				$main::PACKAGES =~ s/,/ /g;
				$autoUpd_cmd .= "$main::PACKAGES ";
			}
			else
			{
				if ($::arch =~ m/ppc/)
				{ #we need to run the command twice, once with --arch ppc, and once without
					$run_count++;

					#$autoUpd_cmd .= "--arch ppc ";
				}
			}
			while ($run_count > 0)
			{
				MessageUtils->message('V', 'IMsgRUN_SMSLOCAL_CMD',
									  $autoUpd_cmd);
				my @results = `$autoUpd_cmd 2>&1`;
				chomp(@results);
				my $autoUpd_exit = $? >> 8;
				$last_command = $autoUpd_cmd;
				$last_exit    = $autoUpd_exit;
				if ($autoUpd_exit != 0)
				{
					$run_count = 0;    #don't run again if there were problems
					  # MessageUtils->message('E', 'EMsgCommandFailed', $autoUpd_cmd, "$! $autoUpd_exit");
					if ($::GLOBAL_EXIT < 2)
					{
						$::GLOBAL_EXIT = 2;
					}
					foreach my $line (@results)
					{
						MessageUtils->message('O', 'IMsgAutoUpdateDetails',
											  $line);
					}
				}
				else
				{
					$autoUpd_cmd .= "--arch ppc ";
					if ($::GLOBAL_EXIT == 2)
					{
						$::GLOBAL_EXIT = 0;
					}
					foreach my $line (@results)
					{
						MessageUtils->message('V', 'IMsgAutoUpdateDetails',
											  $line);
					}
				}
				if ($main::TEST)
				{
					&printTestOutput("Update", @results);
				}

				$run_count--;
			}
		}
	}
	if ($last_exit)
	{
		MessageUtils->message('E', 'EMsgCommandFailed', $last_command,
							  $last_exit);
	}

}

sub erase
{
	my $DEPS;
	my ($rpm, $parent) = @_;
	if (!defined $parent)
	{
		$parent = "";
	}
	if ($::removed{$rpm})
	{
		return;
	}
	my $flag = 0;
	my @rpm_results;
	my $rpm_cmd = "/bin/rpm -ev";
	if ($::cyclic{$rpm} || $main::TEST)
	{    #just test it if it is cyclical
		$rpm_cmd .= " --test";
	}
	$rpm_cmd .= " $rpm";
	if (!$::cyclic{$rpm})
	{
		MessageUtils->message('V', 'IMsgRUN_SMSLOCAL_CMD', $rpm_cmd);
	}
	@rpm_results = `$rpm_cmd 2>&1`;
	my $rpm_exit = $? >> 8;
	if ($rpm_exit != 0)
	{
		my %deps;
		foreach my $line (@rpm_results)
		{
			if (grep /is\sneeded\sby/, $line)
			{
				$DEPS = 1;
				my @tmp = split ' ', $line;
				my $dep = pop @tmp;
				$deps{$dep} = 1;
			}
		}
		my @rem = keys %deps;
		if (@rem)
		{
			foreach my $depend (@rem)
			{
				if ($depend eq $parent)
				{

					#this is a circular dependency -- the child depends on the parent
					#once the other dependencies have been removed, force the removal of this rpm
					$::cyclic{$depend} = 1;
					$flag = 1;

					#print "$depend is dependant on $parent\n";
				}
				else
				{
					&erase($depend, $rpm);
				}
			}
		}
		if (!$DEPS)
		{

			#print "command $rpm_cmd failed on line 337\n";
			MessageUtils->message('E', 'EMsgCommandFailed', $rpm_cmd,
								  $rpm_exit);
			print @rpm_results;
			if ($::GLOBAL_EXIT < 2)
			{
				$::GLOBAL_EXIT = 2;
			}
		}
	}
	else
	{
		$::removed{$rpm} = 1;
		MessageUtils->message('V', 'IMsgRemovedRPM', $rpm);
	}
	if ($DEPS && !$::removed{$rpm})
	{    #it had children that returned
		my @last_rpm;
		if ($::cyclic{$rpm} || $flag)
		{
			$rpm_cmd = "/bin/rpm -ev";
			$rpm_cmd .= " --nodeps";  #its cyclic so just force it to be removed
			if ($main::TEST)
			{
				$rpm_cmd .= " --test";
			}
			$rpm_cmd .= " $rpm";
		}
		MessageUtils->message('V', 'IMsgRUN_SMSLOCAL_CMD', $rpm_cmd);
		@rpm_results = `$rpm_cmd 2>&1`;
		my $rpm_exit = $? >> 8;
		if ($rpm_exit != 0)
		{
			if (!$::TEST)
			{
				#print "command $rpm_cmd failed on line 361\nRESULTS = @rpm_results\n\n";
				MessageUtils->message('E', 'EMsgCommandFailed', $rpm_cmd,
									  $rpm_exit);
				print @rpm_results;
				if ($::GLOBAL_EXIT < 2)
				{
					$::GLOBAL_EXIT = 2;
				}
			}
			else
			{
				MessageUtils->message('I', 'IMsgCANTRemoveRPM', $rpm);
			}
		}
		else
		{
			$::removed{$rpm} = 1;
			if ($main::TEST)
			{
				MessageUtils->message('I', 'IMsgFoundRpmToRemove', $rpm);
			}
			else
			{
				MessageUtils->message('I', 'IMsgRemovedRPM', $rpm);
			}

		}
	}
}

############################################################
# queryAutoupdate
############################################################
sub queryAutoupdate
{

	if (   !(-e "/usr/sbin/autoupdate")
		|| !(-e "/usr/sbin/autoupd")
		|| !(-e "/usr/sbin/autoins"))
	{

		my $rpm_command = "/bin/rpm -q autoupdate";

		#my @rpm_results = `$rpm_command 2>&1`;
		my @rpm_results = NodeUtils->runcmd("$rpm_command", -1);
		my $rpm_exit = $::RUNCMD_RC;
		if (($rpm_exit != 0) && ($rpm_exit != 1))
		{
			MessageUtils->message('E255', 'EMsgCANT_RUN', $rpm_command,
								  "@rpm_results $rpm_exit");
		}
		else
		{
			if ($rpm_exit == 1)
			{
				MessageUtils->message('E1', 'EMsgAutoupdateNotInstalled');
			}
		}
	}
}
############################################################

############################################################
# checkConfigFile
# /var/opt/csm/autoupdate.conf
#
# PLEASE NOTE: THERE IS A COPY OF THIS FUNCTION IN SMSUPDATENODE AND SMSLOCAL
#	       IF YOU CHANGE ONE, PLEASE MAKE SURE TO CHANGE THE OTHER.
#
# Possible attributes are:
# DoDld=0|1		Do (don't do) the download part.
# DoUpdate=0|1		Do (don't do) the update part.
# DoInstall=0|1         Do (don't do) the install part.
# DoKernel=0|1          Do (don't do) the kernel update part.
# DoBoot=0|1		Do  (don't  do)  include  new kernels to the boot manager.
# DoInitRD=0|1		Do (don't do) create an initial ram disk for new kernels.
# DoMerge=0|1		Merge  all  new  rpms  into the distribution directory.
# MergeMatch=0|1	Apply Include/Exclude match to rpms selected for merging. Otherwise only to rpms selected for update.
# MergeAll=0|1		Merge (i.e, copy) rpms for  which  no  local version exists as well.
# DoPurge=0|1		Remove  old versions from the updates directory.
# Passive=0|1		Use passive ftp as default.
# FTPRetry=num		Number  of  retries  if  the  first  connect fails.
# FTPWait=seconds	Time  to  wait  in  seconds  until  the next attempt to connect is made.
# FTPFirewall=host.domain:port
#			FTP firewall to use.
# HTTPSendHost=0|1	Send host name as part of http  requests  by default.   (May  confuse  older  httpd,  but needed for virtual hosts.)
# DldGetInstalled=0|1	Always add  installed  rpms  for  comparison during  download.  (Even  if  a distribution directory is given.)
# DldMatch=0|1		Apply Include/Exclude match to rpms selected for   download.   Otherwise   only  to  rpms selected for update.
# CleanUp=0|1		Do (don't) remove old rpms after  upgrading.
# CleanUpKernel=0|1	Do  (don't)  remove  kernel  rpms which have been removed from the boot manager.
# BootManager=string	Boot manager to use. Currently  lilo(8)  and grub(8)  are  supported.  Default is lilo(8) respectively grub(8)  if  the  corresponding executable is found.
# BootScript=file	Custom  boot script to install the boot manager.
# BootConf=file		Boot manager configuration file. Defaults to /etc/lilo.conf for lilo(8) and /boot/grub/grub.conf for grub(8).
# BootAddAsNew=0|1	Add the boot tag to the  label  of  the  new (current) image upon kernel upgrade.
# BootTag=string	Custom  tag  for  kernel images. Defaults to "-new" for new and "-old"  for  old  images. All  previous  images  with this tag will be removed from the boot manage.
# UseBootTag=string  	Use the boot tag even if the label  contains the full version string.
# KernelExt=ext1,ext2,...
#			Packages with the names matching ^kernel-\d, ^kernel-ext1-\d, ...  are considered  to  be kernel  packages.  Defaults  to  "smp,enterprise,BOOT".
# BestMatch=0|1		Only download the  rpm  which  matches  your machine best.
# RemoveBad=0|1		Do (don't) remove bad rpms (e.g., bad checksum) from the updates directory.
# CheckSig=0|1		Do  (don't)  check  rpm  signatures   before upgrading.
# CheckGPG=0|1		Do  (don't)  check rpm gpg signatures before upgrading.  Will fail if no gpg signature is present.
# Resolve=0|1		Do  (don't)  install new packages to satisfy dependencies.
# DataBase=file		Location of the provides database.  Defaults to  UpdateDir/DataBaseName  if available and /etc/autoupdate.d/DataBaseName else.
# DataBaseName=string	Filename for the provides database. Defaults to autoprovides.db.
# DldUseDB=0|1		Do  (don't)  use  databases  found on remote servers. The content of every file  autoprovides-VERSION.db  will  be added to the provides database if VERSION is newer than  the one we already have.
# DoLog=0|1		Do  (don't)  log all updated, installed rpms to the log file.
# LogFile=file		Location  of  the  log  file.  Defaults to /var/log/autoupdate.log.
# UpdateDir=directory	Directory where the updates are stored.
# InstallDir=directory	Directory where the new rpms are stored. For use with the updateall option. Default is to use the updates directory.
# RPMDir=directory	Directory  where  the  distribution rpms are stored.
# Recurse=0|1		Do (don't) recurse through  all  subdirectories  of  updates directory.  Subdirectories according to  architecture  will  always  be included.
# PostUpdateScript=script
#			Script  to execute after rpms were upgraded.
# PostDldScript=script	Script to  execute  after  rpms  were  downloaded.
# DistVersion=string 	Distribution  version. The string "#DistVersion#" will be replaced by  this  string  in the  update, install and rpm directories and in the default provides data base name.
# DistArch=string	Distribution   architecture.   The    string "#DistArch#" will be replaced by this string in the update and rpm directories.
# Exclude=regexp	Exclude rpms matching (perl) regular expression. Can be used one or more times.
# Include=regexp	Include rpms matching (perl) regular expression. Can be used one or more times.
# DldConfig=file 	Dld configuration files in  DldConfigDir to include. Can be used one or more times.
# DldConfigDir=dir	Directory where dld configuration files are stored. Default is /etc/autoupdate.d/.
# DefaultArch=arch	Default  architecture  to   use   (otherwise 'uname -m').
# DefaultUser=string 	Default user name (anonymous).
# DefaultPass=string	Default password (autoupdate@localhost).
# HTTPExt=ext1,ext2,...	Files  with  these extensions will be parsed during  recursive  search  at  http   sites. Defaults to "html,htm,php,asp".
# ShellEscapes=0 	Disable   shell  escapes  for  configuration files from now on.
# Verbose=0|1		Be verbose.
# Quiet=0|1 		Be quiet.
# Warnings=0|1		Display warnings.
# RPMNameWarnings=0|1	Display warnings for bad rpm names.
# Debug=0|1|2|3		Turn on debugging information.
#
############################################################

sub checkConfigFile
{
	my $config_file = "/var/opt/csm/autoupdate.conf";
	if (!(-f $config_file))
	{    #the file does not exist
		umask(033);
		open(CONFIG, ">$config_file")
		  or MessageUtils->msg($::MSGS, 'E', 'EMsgCANTOPEN', $config_file,
							   "$? $!");
		print CONFIG <<'EOF1';
# /var/opt/csm/autoupdate.conf

DoDld=0
DoUpdate=0
DoInstall=0

#------------------
# Kernel Settings  -- Turn these on to have autoupdate update the kernel
#
# DoKernel=0|1          Do (don't do) the kernel update part.
# DoBoot=0|1		Do (don't do) include new kernels to the boot
#			manager.
# DoInitRD=0|1		Do (don't do) create an initial ram disk for new 
#			kernels.
# CleanUpKernel=0|1	Do (don't) remove kernel rpms which have been
#			removed from the boot manager.
# BootManager=string	Boot manager to use. Currently lilo(8) and grub(8)
#			are supported. Default is lilo(8) respectively 
#			grub(8) if the corresponding executable is found.
# BootScript=file	Custom boot script to install the boot manager.
# BootConf=file		Boot manager configuration file. Defaults to 
#			/etc/lilo.conf for lilo(8) and /boot/grub/grub.conf
#			for grub(8).
# BootAddAsNew=0|1	Add the boot tag to the label of the new 
#			(current) image upon kernel upgrade.
# BootTag=string	Custom tag for kernel images. Defaults to "-new"
#			for new and "-old" for old images. All previous
#			images with this tag will be removed from the boot
#			manager.
# UseBootTag=string 	Use the boot tag even if the label contains the 
#			full version string.
# KernelExt=ext1,ext2,...
#			Packages with the names matching ^kernel-\d, 
#			^kernel-ext1-\d, ... are considered to be 
#			kernel packages. Defaults to "smp,enterprise,BOOT".
#------------------

DoMerge=0
MergeMatch=0
MergeAll=0
DoPurge=0
DldMatch=0
CleanUp=0
BestMatch=0
RemoveBad=0
CheckSig=0
CheckGPG=0
Resolve=1
DoLog=1
Verbose=1
Warnings=1

# DataBase=file		Location of the provides database. Defaults to 
#			UpdateDir/DataBaseName if available and 
#			/etc/autoupdate.d/DataBaseName else.
# DataBaseName=string	Filename for the provides database. Defaults to 
#			autoprovides.db.
# LogFile=file		Location of the log file. Defaults to 
#			/var/log/autoupdate.log.
# UpdateDir=directory	Directory where the updates are stored.    
# InstallDir=directory	Directory where the new rpms are stored. For use with
#			the updateall option. Default is to use the updates 
#			directory.
# RPMDir=directory	Directory where the distribution rpms are stored.
# Recurse=0|1		Do (don't) recurse through all subdirectories of 
#			updates directory. Subdirectories according to 
#			architecture will always be included.
# PostUpdateScript=script
#			Script to execute after rpms were upgraded.
# PostDldScript=script	Script to execute after rpms were downloaded.
# DistVersion=string 	Distribution version. The string "#DistVersion#" will 
#			be replaced by this string in the update, install 
#			and rpm directories and in the default provides data 
#			base name.
# DistArch=string	Distribution architecture. The string "#DistArch#" 
#			will be replaced by this string in the update and 
#			rpm directories.
# DefaultArch=arch	Default architecture to use (otherwise 'uname -m')
# DefaultUser=string 	Default user name (anonymous).
# DefaultPass=string	Default password (autoupdate@localhost).
# ShellEscapes=0 	Disable shell escapes for configuration files 
#			from now on.
# Quiet=0|1 		Be quiet.
# RPMNameWarnings=0|1	Display warnings for bad rpm names.
# Debug=0|1|2|3		Turn on debugging information.
#
EOF1
		close CONFIG;
	}

	#else: for now, if the file is there, assume it is correct

}

#-------------------------------------------------------------------------#
#                                                                         #
#   get_node_info                                                         #
#                     Get required information out of the configinfo      #
#                     file. This file contains attributes and values for  #
#                     the node we are running on.                         #
#                                                                         #
#   Return Codes: 0 - All was successful.                                 #
#                 1 - An error occured.                                   #
#--------------------------------------#----------------------------------#
sub get_node_info
{

	my ($attr, $value);

	if (-f $::CFGINFOFILE)
	{
		unless (open(CFGINFO, "<$::CFGINFOFILE"))
		{

			# Could not open $::CFGINFOFILE file.
			MessageUtils->message('E', 'EMsgCANT_READ_FILE', $::CFGINFOFILE);
			return $::NOK;
		}
		while (<CFGINFO>)
		{
			($attr, $value) = split('=');
			if ($attr eq "InstallOSName")
			{
				$::ostype = $value;
				chomp $::ostype;
			}
			elsif ($attr eq "InstallCSMVersion")
			{
				$::csmvers = $value;
				chomp $::csmvers;
			}
			elsif ($attr eq "InstallDistributionVersion")
			{
				$::osversion = $value;
				chomp $::osversion;
			}
			elsif ($attr eq "InstallDistributionName")
			{
				$::osdistr = $value;
				chomp $::osdistr;
			}
			elsif ($attr eq "InstallPkgArchitecture")
			{
				$::arch = $value;
				chomp $::arch;
			}
			elsif ($attr eq "InstallServiceLevel")
			{
				$::servicelevel = $value;
				chomp $::servicelevel;
			}
		}
		close(CFGINFO);
	}
	return $::OK;
}

# install all RPMS from /csminstall/.../install directory
sub install_from_insdir
{
	my $run_count = 1;
	if (!-e $main::INSTALL_DIR) { return; }
	MessageUtils->message('I', 'IMsgRunningInstall');
	$main::INSTALL_RPMS =~ s/,/ /g;
	my $autoIns_cmd = "/usr/sbin/autoins ";
	$autoIns_cmd .= "--config /var/opt/csm/autoupdate.conf ";
	$autoIns_cmd .= "--updatedir $main::INSTALL_DIR ";
	$autoIns_cmd .= "--rpmdir $main::RPM_DIR ";

	if (!$::NO_DB)
	{
		$autoIns_cmd .= "--database /var/opt/csm/autoprovides.db ";
	}
	else
	{
		$autoIns_cmd .=
		  "--noaddtodb --database /var/opt/csm/tmp.autoprovides.db ";
	}

	#	$autoIns_cmd .= "--addtodb "; #this takes a long time.
	$autoIns_cmd .= "--verbose ";
	if ($main::TEST)
	{
		$autoIns_cmd .= "--test ";
	}
	if ($main::noinsdeps)
	{
		$autoIns_cmd .= "--noresolve ";
	}
	if ($::arch =~ m/ppc/)
	{  #we need to run the command twice, once with --arch ppc, and once without
		$run_count++;

		#$autoIns_cmd .= "--arch ppc ";
	}
	while ($run_count > 0)
	{
		MessageUtils->message('V', 'IMsgRUN_SMSLOCAL_CMD', $autoIns_cmd);
		my @results = `$autoIns_cmd 2>&1`;
		chomp(@results);
		my $autoIns_exit = $? >> 8;
		if ($autoIns_exit != 0)
		{
			$run_count = 0;    #don't run again if there was a problem
			MessageUtils->message(         'E',          'EMsgCommandFailed',
								  $autoIns_cmd, "$! $autoIns_exit");
			if ($::GLOBAL_EXIT < 2)
			{
				$::GLOBAL_EXIT = 2;
			}
			foreach my $line (@results)
			{
				MessageUtils->message('O', 'IMsgAutoUpdateDetails', $line);
			}
		}
		else
		{
			$autoIns_cmd .= "--arch ppc ";
			foreach my $line (@results)
			{
				MessageUtils->message('V', 'IMsgAutoUpdateDetails', $line);
			}
		}
		if ($main::TEST)
		{
			&printTestOutput("Install", @results);
		}

		$run_count--;
	}
	foreach my $group (sort keys %main::groups)
	{
		if (-e "$main::INSTALL_DIR/$group")
		{
			$run_count = 1;
			my $autoIns_cmd = "/usr/sbin/autoins ";
			$autoIns_cmd .= "--config /var/opt/csm/autoupdate.conf ";
			$autoIns_cmd .= "--updatedir $main::INSTALL_DIR/$group ";
			$autoIns_cmd .= "--rpmdir $main::RPM_DIR ";
			if (!$::NO_DB)
			{
				$autoIns_cmd .= "--database /var/opt/csm/autoprovides.db ";
			}
			else
			{
				$autoIns_cmd .=
				  "--noaddtodb --database /var/opt/csm/tmp.autoprovides.db ";
			}

			#	$autoIns_cmd .= "--addtodb "; #this takes a long time.
			$autoIns_cmd .= "--verbose ";
			if ($main::TEST)
			{
				$autoIns_cmd .= "--test ";
			}
			if ($main::noinsdeps)
			{
				$autoIns_cmd .= "--noresolve ";
			}
			if ($::arch =~ m/ppc/)
			{ #we need to run the command twice, once with --arch ppc, and once without
				$run_count++;

				#$autoIns_cmd .= "--arch ppc ";
			}
			while ($run_count > 0)
			{
				MessageUtils->message('V', 'IMsgRUN_SMSLOCAL_CMD',
									  $autoIns_cmd);
				my @results = `$autoIns_cmd 2>&1`;
				chomp(@results);
				my $autoIns_exit = $? >> 8;
				if ($autoIns_exit != 0)
				{
					$run_count = 0;    #don't run again if there was a problem
					if ($::GLOBAL_EXIT < 2)
					{
						$::GLOBAL_EXIT = 2;
					}
					foreach my $line (@results)
					{
						MessageUtils->message('O', 'IMsgAutoUpdateDetails',
											  $line);
					}
				}
				else
				{
					$autoIns_cmd .= "--arch ppc ";
					if ($::GLOBAL_EXIT == 2)
					{
						$::GLOBAL_EXIT = 0;
					}
					foreach my $line (@results)
					{
						MessageUtils->message('V', 'IMsgAutoUpdateDetails',
											  $line);
					}
				}
				if ($main::TEST)
				{
					&printTestOutput("Install", @results);
				}

				$run_count--;
			}
		}
	}
}

#replace all global vars with /csminstall with $::CSMCLIENTMNTDIR
sub fixMountPoint
{

	if (defined $main::UPDATE_DIR)
	{
		$main::UPDATE_DIR =~ s,/csminstall,$::CSMCLIENTMNTDIR,g;
	}
	if (defined $main::RPM_DIR)
	{
		$main::RPM_DIR =~ s,/csminstall,$::CSMCLIENTMNTDIR,g;
	}
	if (defined $main::BASE_DIR)
	{
		$main::BASE_DIR =~ s,/csminstall,$::CSMCLIENTMNTDIR,g;
	}
	if (defined $main::INSTALL_RPMS)
	{
		$main::INSTALL_RPMS =~ s,/csminstall,$::CSMCLIENTMNTDIR,g;
	}
	if (defined $main::PACKAGES)
	{
		$main::PACKAGES =~ s,/csminstall,$::CSMCLIENTMNTDIR,g;
	}
	if (defined $main::INSTALL_DIR)
	{
		$main::INSTALL_DIR =~ s,/csminstall,$::CSMCLIENTMNTDIR,g;
	}

}


#give formatted msgs for -t option
sub printTestOutput
{
	my ($op, @results) = @_;
	my $print_rpms = "";
	my $flag = 0;
	foreach my $line (@results)
	{
		if ($line =~ m/^  (.*\.rpm$)/)
		{
			$print_rpms = "$1";
			MessageUtils->message('I', "IMsgFoundRpmsTo$op", $print_rpms);
			$flag++;
		}

	}
	if ($flag == 0)
	{
		MessageUtils->message('I', "IMsgNoRpmsFoundTo$op");  
	}
}
