#!/usr/bin/perl -w
#-----------------------------------------------------------------------------#
#  Copyright (C) 2001 - 2002 Multi-Tech Systems Inc., USA
#  All Rights Reserved
#  Multi-Tech Systems, Inc., 2205, Woodale Dr, Mounds View MN USA
#-----------------------------------------------------------------------------#
#  ModName: Web GUI - Interface
#  Version: 3.25
#  Date: 2005-11-08
#  Modification History - Begin
#  Modification History - End


# Description		Used to get all updates from the autoupdate server


$SIG{QUIT} = 'interrupt';
$SIG{INT} = 'interrupt';
$SIG{TERM} = 'interrupt';

sub interrupt
{
	if (-e "/etc/multiconf/scripts/$rpmlist")
	{
		`rm -f /etc/multiconf/scripts/$rpmlist`;
	}
	if (-e "/etc/multiconf/scripts/$rpmcheck")
	{
		`rm -f /etc/multiconf/scripts/$rpmcheck`;
	}
	$SIG{QUIT} = 'DEFAULT';
	$SIG{INT} = 'DEFAULT';
	$SIG{TERM} = 'DEFAULT';
}

system("touch /etc/multiconf/updatelog");
open (UPDATELOG, ">/etc/multiconf/updatelog");
print UPDATELOG "AutoUpdate Started\n";
close (UPDATELOG);

# If the file doesn't exist, its treated as a fresh installation upgrade.
# Create the file with index as '1'
if (!(-e "/etc/multiconf/autostatusindex")) {
	system("echo 1 > /etc/multiconf/autostatusindex");
}

# we have an index which is called status index. if any session crashes, the place where the task crashed is shown by this index.
$previous = `cat /etc/multiconf/autostatusindex`;
chomp ($previous);

#Calling diskspace to do cleanup. Also the cron and logging is stopped so that it doesnot hamper the installation

system("/etc/multiconf/scripts/diskspace");

$retries = 0;
# check if the previous state is 0 or 1. '0' here represents that autoupdate has never been invoked on this machine. A '1' represents that autoupdate has run some time back and has exited normally.
if($previous == 1)
{
	#Some rpms might start logging.
	#my $syslog_status=`/etc/init.d/syslog-ng status`;
	#chomp($syslog_status);
	#if ($syslog_status	=~ /is running/) 
	#{
	#	system("/etc/init.d/syslog-ng stop");
	#}
	system("cp -f /etc/multiconf/scripts/update_check /etc/cron.thirtymins/");
	system("echo 0 > /etc/multiconf/mailstatus");
	first_state();
}
# check if the status is 2 or 3. if it is 2, it represents that download was in progress and the session has crashed. 3 represents that rpm signature verification was in progress when the session has crashed.
elsif($previous == 2)
{
	second_state();
}
# check if the status is 4. if so, it represents that rpm installation is in progress.
elsif($previous == 3)
{
	third_state();
}
#For all the other remaining possibilities, this is the status.
else
{
	system("echo 1 > /etc/multiconf/autostatusindex");
	system("rpm -e --nodeps lvpngeneral-CF");
	exit (0);
} 

sub first_state
{

	#Invoke autodld to get the latest rpms
	open (UPDATELOG, ">>/etc/multiconf/updatelog");
	print UPDATELOG "Downloading packages\n";
	close (UPDATELOG);
	$return = system("autoupdate --debug 1");
	#If autodld return is not fine, it means there was something wrong in the setup or link failure, etc.
	if($return!=0)
	{
		if(-e "/etc/multiconf/noupdate")
		{
			my $noupdates = `cat /etc/multiconf/noupdate`;
			chomp($noupdates);
			if($noupdates == 1)
			{
				`echo 0 > /etc/multiconf/noupdate`;
				system("sync");
				exit(0);
			}
		}
		system("echo 1 > /etc/multiconf/autostatusindex");
		open (UPDATELOG, ">>/etc/multiconf/updatelog");
		print UPDATELOG "Downloading packages failed\n";
		close (UPDATELOG);
		sendmail ("Downloading packages failed", "no");
		# flush the filesystem buffers
		system("sync");
		exit(0);
	}
	system(" echo 2 > /etc/multiconf/autostatusindex");
	second_state();
}

#When it is called directly, it indicates that the earlier session has crashed at either download or signature checking. if it is called in the normal flow, it indicates that integrity of the rpms has to be checked.

sub second_state
{
	#Get  a temperory file
	$rpmlist = `/etc/multiconf/scripts/gettempfile`;
	#Get the list of downloaded rpms from /var/spool/autoupdate diretoryo	 
	# do a version sort using -v option of ls
	system("ls -1v /var/spool/flash/autoupdate/*.rpm | grep -v lvpngeneral-CF > /etc/multiconf/scripts/$rpmlist");
	#Set the update status to 3 for SIGNATURE CHECK
	#Flush the filesystem buffers
	system("sync");
	open (TEMP, "/etc/multiconf/scripts/$rpmlist");
	while(<TEMP>)
	{
		chomp($_);
		# get each rpm by name and check its md5 checksum. store the output into a temperory file. 
		$sigreport = `rpm --checksig --nogpg $_ | cut -d: -f2`;
		chomp($sigreport);
		if( $sigreport ne " md5 OK")
		{
			# if the signature were nt okay, remove the rpm
			system("rm -f $_");
			if( $retries <= 1)
			{
				$retries++;
				open (UPDATELOG, ">>/etc/multiconf/updatelog");
				print UPDATELOG "Signature Check for $_ Failed. Retrying download.\n";
				close (UPDATELOG);
				first_state();
			}
			else
			{
				open (UPDATELOG, ">>/etc/multiconf/updatelog");
				print UPDATELOG "Signature Check for $_ Failed. Downloading aborted.\n";
				close (UPDATELOG);
				sendmail ("Signature Check Failed for $_", "yes");
				unlink("/etc/multiconf/autostatusindex");
				exit 1;
				#$retries=0;
			}
		}
	}
	close(TEMP);
	unlink("/etc/multiconf/scripts/$rpmlist");
	system("sync");
	system(" echo 3 > /etc/multiconf/autostatusindex");
	third_state();
}

# Signature Check has been successful. Now it is time for RPM Installation
sub third_state
{
	system ("sleep 5");
	my $lvpn_inst_rpm = `rpm -q lvpngeneral-CF`;
	chomp($lvpn_inst_rpm);
	if ($lvpn_inst_rpm =~ /not installed/)
	{
		#$lvpnrpm = `ls /var/spool/autoupdate | grep lvpngeneral | cut -d/ -f5`;
		# Deal with multiple lvpngeneral rpms present in /var/spool/autoupdate
		$lvpnrpm = `ls -1vr /var/spool/flash/autoupdate/lvpngeneral-CF* 2>/dev/null | grep -m 1 lvpngeneral-CF | cut -d/ -f6`;
		if ($lvpnrpm eq "")
		{
			open (UPDATELOG, ">>/etc/multiconf/updatelog");
			print UPDATELOG "Error in downloading RPMs.\n";
			close (UPDATELOG);
			system("echo 1 > /etc/multiconf/autostatusindex");
			system("rm -f /var/spool/flash/autoupdate/lvpngeneral*");
			sendmail ("Error in downloading RPMs", "no");
			system("sync");
			exit(0);
		}

		chdir("/var/lib/rpm");
		unlink("presentrpm.zip");
		system("zip presentrpm.zip *");
		# Backup autoupdates config file which contains the directory to download
		chdir("/etc/autoupdate.d");
		system("zip /var/lib/rpm/presentrpm.zip autoupdate.dld");

		$instvalue = system("rpm -U --nodeps /var/spool/flash/autoupdate/$lvpnrpm");
		if ($instvalue!=0)
		{
			open (UPDATELOG, ">>/etc/multiconf/updatelog");
			print UPDATELOG "RPM list installation failed. Aborting the autoupdate.\n";
			close (UPDATELOG);

			chdir("/var/lib/rpm");
			system("unzip -oX presentrpm.zip");
			system("mv -f autoupdate.dld /etc/autoupdate.d");
			system("rm -f /var/lib/rpm/presentrpm.zip");
			system("echo 1 > /etc/multiconf/autostatusindex");
			system("rm -f /var/spool/flash/autoupdate/lvpngeneral*");
			sendmail ("RPM List Installation Failed", "yes");
			# flush the filesystem buffers
			system("sync");
			exit(1);
		}
		# For future update versions - suppose new autoscript is not copied to lvpn general
		# This call is for installing the rpms from rpmlist
		first_state();
	}
	else
	{
		$NewRPMFound = 0;
		open(LISTRPM, "/etc/multiconf/confscripts/rpmdld");
		@rpmlist = <LISTRPM>;
		close(LISTRPM);
		while ($list_entry = shift (@rpmlist))
		{
			chomp($list_entry);
			if ($list_entry eq "")
			{
				next;
			}
	
			$NewRPMFound = 1;
	
			$rpmtoinst = $list_entry . "\.i386\.rpm";
			print "RPM to be installed is $rpmtoinst\n";
			chdir("/var/lib/rpm");
			unlink("presentrpm.zip");
			system("zip presentrpm.zip *");

			$rpmtodel = `rpm -qa | grep -v lvpngeneral-CF`;
			chomp($rpmtodel);

		# Added this since -e --justdb with RouteFinder did not work without --nodeps and it used to proceed with the installation and did screw up the box
		# 23 April 2004
			system("rpm -e --justdb --nodeps $rpmtodel");
			if ($rpmtoinst =~ /RF660/)
			{
				`echo "Starting Installation Of $list_entry" >> /etc/multiconf/updatelog`;
				$rpminst = system("rpm -U --nodeps /var/spool/flash/autoupdate/$rpmtoinst");
			}
			else
			{
				`echo "Starting Installation Of $list_entry" >> /etc/multiconf/updatelog`;
				$rpminst = system("export LD_LIBRARY_PATH=/usr/lib;rpm -Uvh --nodeps /var/spool/flash/autoupdate/$rpmtoinst >> /etc/multiconf/updatelog");
			}

			if ($rpminst!=0)
			{
				open (UPDATELOG, ">>/etc/multiconf/updatelog");
				print UPDATELOG "RPM $list_entry installation Failed.Aborting.\n";
				close (UPDATELOG);
				chdir("/var/lib/rpm");
				system("unzip -oX presentrpm.zip");
				system("rm -f /var/lib/rpm/presentrpm.zip");
				system("echo 3 > /etc/multiconf/autostatusindex");

				open(DLDLIST, ">/etc/multiconf/confscripts/rpmdld");
				print DLDLIST @rpmlist;
				close (DLDLIST);

				sendmail ("Installing $list_entry failed", "yes");
				# flush the filesystem buffers
				system("sync");
				exit(0);
			}
			open (UPDATELOG, ">>/etc/multiconf/updatelog");
			print UPDATELOG "RPM $list_entry installation successful.\n";
			close (UPDATELOG);
		}
		#Since we are downloading rpm one by one and installing, we need to check whether the RPM installed is of the same version as that of lvpn-general,if not we do a cleanup and call first state again to continue with the installation.
		$rpmcurrent = `rpm -qa | grep RouteFinder-CF|cut -d "-" -f3,4`;
		chomp($rpmcurrent);
		$lvpncurrent = `rpm -qa | grep lvpngeneral-CF|cut -d "-" -f3,4`;
		chomp($lvpncurrent);
		if($lvpncurrent ne $rpmcurrent)
		{
			system("rm -f /var/spool/flash/autoupdate/$rpmtoinst");
			first_state();
		}
	
		
		my $mailstatus=`cat /etc/multiconf/mailstatus`;
		chomp($mailstatus);
		if ($mailstatus eq "0")
		{
			open (UPDATELOG, ">>/etc/multiconf/updatelog");
			if ($NewRPMFound == 0)
			{
				print UPDATELOG "No updates found.\n";
			}
			else
			{
				print UPDATELOG "Autoupdate successful.\n";
			}
			close (UPDATELOG);
		}

		system("rm -rf /etc/multiconf/confscripts");
		unlink ("/etc/multiconf/autostatusindex");

		`perl -pi -e 's/Dir=(.*)\\\/rpms/Dir=\$1/g' /etc/autoupdate.d/autoupdate.dld`;
		`perl -pi -e 's/Dir=(.*)\\\/RF3-09d/Dir=\$1/g' /etc/autoupdate.d/autoupdate.dld`;
		system("rpm -e --nodeps lvpngeneral-CF");
		system("rm -f /var/spool/flash/autoupdate/*");

		system("sync");
		if ($mailstatus eq "0")
		{
			system("echo 1 > /etc/multiconf/mailstatus");
			$statstr = "System update completed successfully";
			sendmail ($statstr, "yes");
		}
		system("rm -f /etc/cron.thirtymins/update_check");

		if (-e "/.rpm_update_needs_reboot")
		{
			`echo "Rebooting..." >> /etc/multiconf/updatelog`;
			`/bin/rm -f /.rpm_update_needs_reboot`;
			# Its because update web page refreshes every 10 sec
			sleep 20;
			`reboot`;
		}
	}
}		

sub sendmail ()
{
	my ($statusstr, $sendlog) = @_;
	if ($sendlog eq "yes")
	{
		$logstr = "The system update log file is attached for your reference\n";
		$logfile = "\/etc\/multiconf\/updatelog";
	}
	else
	{
		$logstr = "";
	}

	my $NotifyUser = `/etc/multiconf/scripts/settings emailnotify check 'Auto System update'`;	

	if (-e "/etc/multiconf/mailids/email.conf" && ($NotifyUser eq 'yes'))
	{
		open (MAILIDS, "/etc/multiconf/mailids/email.conf") || die "Cannot open mail id list file\n";
		$maillist = "";
		$AdminIdPresent = 0;
		while (<MAILIDS>)
		{
			$AdminIdPresent = 1;
			$mailid = $_;
			chomp ($mailid);
			if ($maillist eq "")
			{
				$maillist = $mailid;
			}
			else
			{
				$maillist = $maillist . " " . $mailid;
			}
		}
		close (MAILIDS);
		if ($AdminIdPresent == 1)
		{
			$datetoprint = `date +"%Y-%m-%d %H:%M:%S"`;
			chomp ($datetoprint);
			$hostname = `hostname`;
			chomp ($hostname);
			$subject = $hostname . " - System Update";
			if ($logstr eq "")
			{
				`echo "System Update on $datetoprint.\n\nStatus: $statusstr.\n" | mutt -s "$subject" $maillist`;
			}
			else
			{
				`echo "System Update on $datetoprint.\n\nStatus: $statusstr.\n$logstr" | mutt -s "$subject" -a $logfile $maillist`;
			}
		}
	}
}
