#!/usr/bin/perl -w
##############################################
# lvpn version of autoupdate                 #
# G.Vinubalajii                              #
# License: GPL                               #
##############################################

##############################################
# autoupdate                                 #
# Gerald Teschl <Gerald.Teschl@univie.ac.at> #
# Copyright: GPL                             #
# Version: 3.1.9                             #
##############################################


use Net::FTP;
use Getopt::Long;
use File::Copy;
use IO::File;
use POSIX;

use strict;
use vars qw($showhelp $showversion $Host $Port $User 
	$Pass $Protocol @DldDirs @DldConfig 
	@AllRPMs @DownloadedRPMs @rpmlist);

# Make sure we understand the errors of rpm
$ENV{'LANG'}= "en_US";
# Needed when run from cron on older versions 
autoflush STDOUT;
autoflush STDERR;

# Default behavior
my $ritem = "";
my $DoDld = 0;
my $DldAll = 0;
my $DldRecurse = 0;
my $DefaultPassive = 1;
my $Passive = $DefaultPassive;
my $DefaultFTPRetry = 0;
my $FTPRetry = $DefaultFTPRetry;
my $DefaultFTPWait = 10;
my $FTPWait = $DefaultFTPWait;
my $Firewall = "";
my $DoUpdate = 0;
my $Recurse = 0;
my $MaxRecurse = 100;
my $DefaultUser = "anonymous";
my $DefaultPass = "autoupdate\@localhost";
my $DoLog = 0;
my $ShellEscapes = 1;
my $Test = 0;
my $Verbose = 0;
my $Quiet = 0;
my $Warnings = 1;
my $DefaultRPMNameWarnings = $Warnings;
my $RPMNameWarnings = $DefaultRPMNameWarnings;
my $Debug = 0;

# Default file locations
my $URL = "";
my $UpdateDir = "/var/spool/flash/autoupdate";
my $RPMDir = "";
my $ConfigDir = "/etc/autoupdate.d";
my $DldConfigDir = $ConfigDir;
my $ConfigFile = "$ConfigDir/autoupdate.conf";
my $LogFile= "/var/log/autoupdate.log";
#Status of diskspace
my $spacepresent=0;
# Path to helper applications
my $RPM = "/bin/rpm";

# Internal variables (do not change).
my $Version = "3.1.9";
my $USAGE = "Usage:  auto(dld|get|upd|ins|mrg|prg) [ options ], where options are:

  --(no)dld                      Download new rpms.
  --url [user\@]host[/dir]       Download new rpms from this url.
  --dldconfig file1[,file2[,..]] Download configuration files to include.
  --dldall                       Download all new rpms from remote site.
  --(no)dldrecurse               Recurse through all directories at url.
  --(no)passive                  Use (don't use) passive ftp.
  --(no)checksig                 Check rpm signature.
  --updatedir                    Directory containing the rpms to be updated.
  --installdir                   Directory containing the rpms to be installed.
  --rpmdir                       Directory containing the distribution rpms.
  --logfile                      Log file to use.
  --(no)log                      Log updated rpms.
  --config file                  Configuration file.
  --compare ver1,ver2            Compare two version strings.
  --test                         Test mode.
  --(no)verbose                  Be verbose.
  --(no)quiet                    Be quiet.
  --(no)warnings                 Display warnings.
  --debug 1|2|3                  Show debugging info.
  --version                      Print version and exit.
See autoupdate(8) for more information.
";
my $cwd = "";

######################
# Strips unwanted stuff from a directory
######################

sub Strip_Dir
{
my $old;
do {
	$old=$_[0];
	$_[0] =~ s/\/[^\/]+\/\.\.\//\//g;
	$_[0] =~ s/\/\.?\//\//g;
	$_[0] =~ s/^\/\.\.\//\//g;
} while ($_[0] ne $old);
if ($_[1] and $_[0] =~ /^(.*)\/\.?$/) {
	$_[0] = $1;
}

}

######################
# Splits a file name into parts
######################

sub Split_File
{
my $item= $_[0];
my ($path, $file);

chomp($item);
if ( $item =~ /^(.*\/)([^\/]+)$/ ) {
	($path, $file)= ($1, $2);
} else {
	($path, $file)= ("", $item);
}

return ($path, $file);
}

######################
# Splits an rpm name into parts
######################

sub Split_RPM
{
my $item= $_[0];
my ($name, $version, $arch);

chomp($item);
if ( $item=~/^(.+)-([^-]+-[^-]+)\.([^.]+)\.rpm$/ ) {
	($name, $version, $arch) = ($1, $2, $3);
} elsif ( $item=~/^(.+)-(\d[^-]*)\.([^.]+)\.rpm$/ ) {
	($name, $version, $arch) = ($1, $2, $3);
	print STDERR "Warning: Bad rpm name: '$item'\n" if $RPMNameWarnings;
} else {
	($name, $version, $arch) = ("", "", "");
	print STDERR "Warning: Illegal rpm name: '$item'\n" if $RPMNameWarnings;
}

return ($name, $version, $arch);
}


######################
# Check the size of the rpm to be downloaded
######################
sub checkspace
{
	my $ftp;
	my $FTPDebug;	
	my $rpmtocheck = shift;
	my $directory=shift;
	chomp $directory;
	chomp $rpmtocheck;
	#my $dir_temp=split($rpmtocheck
  $Port= getservbyname("ftp","tcp");

	unless ($Port) 
	{ #Just to be sure
		$Port= 0;
    $Port= 21 if ($Protocol eq "ftp");
	}
  if ( $Host =~ /^(.*):(\d+)$/ ) 
	{
		$Host=$1;
    $Port=$2;
	}

	if ($User) 
	{
		print "Fetching rpms from '$Protocol://$User\@$Host'.\n" if $Debug;
  } 
	else 
	{
		print "Fetching rpms from '$Protocol://$Host'.\n" if $Debug;
    ($User, $Pass) = ($DefaultUser, $DefaultPass);
    print "User='$User' Pass='$Pass'.\n" if ($Protocol eq "ftp" and $Debug >1);
	}
  print "Using port: $Port. Passive=$Passive.\n" if ($Debug >1);

  chdir($UpdateDir);

  # The ftp login and connection settings starts here
  unless ($FTPRetry >= 0) 
	{
  	$FTPRetry= 0;
  }
  $FTPRetry++;
 
	while ( ! ($ftp = Net::FTP->new($Host, Debug => $FTPDebug, Passive => $Passive, Firewall => $Firewall, Port => $Port)) ) 
	{
  	$FTPRetry--;
    if ($FTPRetry <= 0) 
		{
        print STDERR "Error: Failed to connect to $Host.\n";
        $@ =~ s/Net::FTP/FTP errror/;
        print STDERR "$@\n";
        return 1;
		}
		else 
		{
			print "Could not connect to $Host. Will try ". $FTPRetry ." more time(s).\n" if $Verbose;
      $@ =~ s/Net::FTP/FTP errror/;
      print "$@\n" if $Debug;
      sleep $FTPWait;
		}
	}

  while ( ! $ftp->login($User,$Pass) ) 
	{
  	$FTPRetry--;
    if ($FTPRetry <= 0) 
		{
			print STDERR "Error: Failed to login at $Host: ", $ftp->message;
      return 1;
		} 
		else 
		{
			print "Could not login to $Host. Will try ". $FTPRetry ." more time(s).\n" if $Verbose;
      print "FTP message: ", $ftp->message if $Debug;
      sleep $FTPWait;
		}
	}
	$ftp->binary();
	my $total = 0;
	my $list_entry;

	$ftp->cwd($directory);
	my @list = $ftp->dir();

	foreach $list_entry(@list)
	{
		if(($list_entry =~ m/$rpmtocheck/) && ($list_entry !~ m/^d/))
		{
    	my @array = split(' ',$list_entry);
      chomp $array[4];
      $total += $array[4];
			last;
		}
	}
 	system("sync");
	my $dsavail = `df / |tr -s " " |cut -d " " -f4 |grep -v vail`;
	chomp $dsavail;
	my $avail = ($dsavail * 1024) - $total;
	if ($avail >= (3 * $total))
	{
		open (UPDATELOG, ">>/etc/multiconf/updatelog");
		print UPDATELOG "Enough space for installation of $rpmtocheck\n";
		close (UPDATELOG);
		$spacepresent=1;		
	}
	else
	{
		$spacepresent=0;
		open (UPDATELOG, ">>/etc/multiconf/updatelog");
		print UPDATELOG "There isnt enough space for installation of $rpmtocheck\n";
		print UPDATELOG "Aborting the installation\n";
		close (UPDATELOG);
		sendmail ("RPM List Installation Failed", "yes");
    # flush the filesystem buffers
    system("sync");
    exit(1);
		
	}
}

######################
# Recursively find rpms (ftp)
######################
sub Get_RPMs_ftp
{

my $ftp = shift;
my @dirs = @_;
my ($dir, $item);
my @rpms = ();

foreach $item (@dirs) {
	if ($item =~ /^\.(\/.*)$/) {
		$item= $ftp->pwd() . $1;
	}
	if ($item eq ".") {
		$item= $ftp->pwd();
	}
}		

print "  Getting list of remote rpms (ftp):\n" if $Debug;
#open (UPDATELOG, ">>/etc/multiconf/updatelog");
#print UPDATELOG "Inside Get_RPMs_ftp\n";
#close (UPDATELOG);


foreach $dir (@dirs) {
	print "    $dir\n" if $Debug;
	unless ( $ftp->cwd($dir) ) {
		print STDERR "Error: Failed to check directory at $Host: ";
		if ($ftp->message !~ /$dir/) {
			print STDERR "$dir: ";
		}
		if ($ftp->message) {
			print STDERR $ftp->message;
		} else {
			print STDERR "Timeout (?)\n";
		}
		next;
	}
	if ($DldRecurse) {
		# Recurse through all of the sub-directories
		foreach $item ( $ftp->dir() ) {
			# |Attributes|HLs|Owner|Group|Size|Date|Name|
			my ($attr,$filename) = (split(/\s+/,$item))[0,-1];
			next if ($filename eq "." or $filename eq "..");
			if ($filename =~ /\.rpm$/ and $attr !~ /^d/) {
						push(@rpms, "$dir/$filename");
				
				next;
				}	
			if ( $attr =~ /^d/ ) {
				# Directory
			} elsif ( $attr =~ /^l/ ) {
				# Link
				next unless ($ftp->cwd($filename));
				$ftp->cwd($dir);
			} else {
				next;
			}
			$filename="$dir/$filename";
			
			# Count the number of subdirs
				if ( $filename =~ tr@/@@ > $MaxRecurse ) 
				{
					print STDERR "Warning: Maximum number of ftp subdirs exceeded
						for: $item\n" if $Warnings;
				} 
				else 
				{
					push(@dirs,$filename);

				}
		
		
		}
	} else {
		foreach $item ( $ftp->ls() ) {
			next unless ($item =~ /\.rpm$/ );
			if($item =~ /lvpngeneral-CF/)
			{
				push(@rpms, "$dir/$item");	
			
			}
				
		}
	}
}

return @rpms;
}

######################
# Read in configuration.
######################

sub Read_Config
{
my ($val, $var);
my $file = shift;
@DldConfig=();

return 0 unless $file;
print "Reading config file: $file\n" if ($Debug >1);

$val=(stat($file))[2];
if ( $val and ($val >> 1)%2 ) {
	die("Fatal: Configuration file '$file' is world writeable!");
	return 1;
}

unless (open(FILE,"<$file")) {
  print STDERR "Error: Could not open: $file ($!)\n";
  return 1;
}

while (<FILE>) {
	chomp;
	next if ( $_ =~ /^#/ );
	next unless ($_ =~/\s*(\w+)\s*=\s*(.*)/);
	($var, $val)= ($1, $2);
	$var =~ s/DoFTP/DoDld/; # Old syntax
	$var =~ s/FTPConfig/DldConfig/; # Old syntax
	$var =~ s/PostFTPScript/PostDldScript/; # Old syntax
	$var =~ s/MatchMerge/MergeMatch/; # Old syntax
	$var =~ s/(Update|RPM)s/$1/; # Old syntax
	$var =~ s/^Dir(.+)$/$1Dir/; # Old syntax
	$var =~ s/UpdateAll/Install/; # Old syntax
	$var =~ s/UpdateKernel/Kernel/; # Old syntax
	$var =~ s/Lilo/Boot/; # Old syntax
	$val="" unless (defined($val));
	if ($val =~ /^`(.+)`$/) {
		if ($ShellEscapes) {
			chomp($val = `$1`);
		} else {
			print STDERR "Warning: Shell escapes disabled ('$var').\n" if $Warnings;
			next;
		}
	} 
	if ( $var eq "ShellEscapes") {
		$ShellEscapes = 0 unless ($val);
	} elsif ( $var eq "Debug" and $val =~/^[0-9]$/ ) {
		$Debug = $val;
	} elsif ( $var eq "Verbose" ) {
		$Verbose = $val;
	} elsif ( $var eq "Quiet" ) {
		$Quiet = $val;
	} elsif ( $var eq "Warnings" ) {
		$Warnings = $val;
	} elsif ( $var eq "RPMNameWarnings" ) {
		$DefaultRPMNameWarnings = $val;
	} elsif ( $var eq "DoDld" ) {
		$DoDld = $val;
	} elsif ( $var eq "DoLog" ) {
		$DoLog = $val;
	} elsif ( $var eq "LogFile" ) {
		$LogFile = $val;
	} elsif ( $var eq "UpdateDir" ) {
		$UpdateDir = $val;
	} elsif ( $var eq "RPMDir" ) {
		$RPMDir = $val;
	} elsif ( $var eq "DefaultUser" ) {
		$DefaultUser = $val;
	} elsif ( $var eq "DefaultPass" ) {
		$DefaultPass = $val;
	} elsif ( $var eq "Passive" ) {
		$DefaultPassive = $val;
	} elsif ( $var eq "FTPRetry" and $val =~/^[0-9]+$/) {
		$DefaultFTPRetry = $val;
	} elsif ( $var eq "FTPWait" and $val =~/^[0-9]+$/) {
		$DefaultFTPWait = $val;
	} elsif ( $var eq "FTPFirewall") {
		$Firewall = $val;
	} elsif ( $var eq "DldConfigDir" ) {
		$DldConfigDir = $val;
	} elsif ( $var eq "DldConfig" ) {
		push(@DldConfig, $val) if $val;
	} else {
		print STDERR "Warning: Unknown variable '$var' or bad value '$val' in $file.\n" if $Warnings;
	}
}
close (FILE);

return 0;
}

######################
# Read in dld configuration.
######################

sub Read_Dld_Config
{
my ($val, $var);
my $BaseDir= "";
my $file = shift;

if (-d $ConfigDir) {
	chdir($ConfigDir) || die("Fatal: Could not cd to: $ConfigDir ($!)");
}
if ( -f $file ) {
	# fine
} elsif ( -f "$file.dld") {
	$file = "$file.dld";
} elsif ( -f "$file.get") {
	$file = "$file.get";
} elsif ( -f "$file.ftp") {
	$file = "$file.ftp";
} elsif ( -f "$cwd/$file") {
	$file = "$cwd/$file" if ($cwd);
}

$Host= "";
$User= "";
$Pass= "";
$Protocol= "ftp";
$DldAll= 0;
$DldRecurse= 0;
$FTPRetry= $DefaultFTPRetry;
$FTPWait= $DefaultFTPWait;
$Passive= $DefaultPassive;
$RPMNameWarnings= $DefaultRPMNameWarnings;
@DldDirs= ();

print "\nReading dld config file: $file\n" if $Debug;

$val=(stat($file))[2];
if ( $val and ($val >> 1)%2 ) {
	print STDERR "Warning: Skipping world writeable configuration file: $file\n" if $Warnings;
	return 1;
}

unless (open(FILE,"<$file")) {
  print STDERR "Error: Could not open: $file ($!)\n";
  return 1;
}

while (<FILE>) {
	chomp;
	next if ( $_ =~ /^#/ );
	next unless ($_ =~/\s*(\w+)\s*=\s*(.*)/);
	($var, $val)= ($1, $2);
	$var =~ s/FTPAll/DldAll/; # Old syntax
	$var =~ s/FTPRecurse/DldRecurse/; # Old syntax
	$var =~ s/^Dir(.+)$/$1Dir/; # Old syntax
	$val="" unless (defined($val));
	if ($val =~ /^`(.+)`$/) {
		if ($ShellEscapes) {
			chomp($val = `$1`);
		} else {
			print STDERR "Warning: Shell escapes disabled ('$var').\n" if $Warnings;
			next;
		}
	}
	if ( $var eq "Host" ) {
		$Host = $val;
	} elsif ( $var eq "Protocol" ) {
		$Protocol = $val;
	} elsif ( $var eq "User" ) {
		$User = $val;
	} elsif ( $var eq "Pass" ) {
		$Pass = $val;
	} elsif ( $var eq "Passive" ) {
		$Passive = $val;
	} elsif ( $var eq "RPMNameWarnings" ) {
		$RPMNameWarnings = $val;
	} elsif ( $var eq "DldAll" and $val =~/^[0-2]$/) {
		$DldAll = $val;
 	} elsif ( $var eq "DldRecurse" ) {
 		$DldRecurse = $val;
	} elsif ( $var eq "FTPRetry" and $val =~/^[0-9]+$/) {
		$FTPRetry = $val;
	} elsif ( $var eq "FTPWait" and $val =~/^[0-9]+$/) {
		$FTPWait = $val;
	} elsif ( $var eq "BaseDir" ) {
		if ($val =~ /^(.*)\/$/) {
			$BaseDir = $1;
		} else {
			$BaseDir= $val;
		}
	} elsif ( $var eq "Dir" ) {
		if ($val =~ /^\/(.*)$/) {
			$val=$1;
		}
		$val= "$BaseDir/$val";
		push(@DldDirs, $val);
	} else {
		print STDERR "Warning: Unknown variable '$var' or bad value '$val' in $file.\n" if $Warnings;
	}
}
close (FILE);

unless ($Host) {
	print STDERR "Error: No host given in $file.\n";
	return 1;
}
unless (@DldDirs) {
	print STDERR "Error: No dld directories given in $file.\n";
	return 1;
}

return 0;
}


######################
# Get RPMs from remote site
######################

sub Get_Remote_RPMs
{
my ($ftp, $dir, $subdir, $item, $name, $version, @AllDldRPMs, @DldRPMs );
my @requirements= ();
my $FTPDebug=0;
my $retval=0;
if ( $Debug > 2 ) { $FTPDebug =1; }

@DldRPMs=();
my $lvpn_inst_rpm = `rpm -q lvpngeneral-CF`;
chomp($lvpn_inst_rpm);

# Check if lvpn general is installed or not
# If its installed create a list of rpms(RouteFinder and RF660) to download
if ($lvpn_inst_rpm !~ /not installed/) {
	print "inside not installed\n";
	my $list_entry;
#	my $instrpm = `rpm -qa | grep -v lvpngeneral-CF`;
	my $instrpm = `rpm -qa | grep RouteFinder-CF`;
	chomp($instrpm);

	#Get the list of RPMs to be installed.
	open(LISTRPM, "/etc/multiconf/confscripts/rpmlist");
	my @rpmtemplist = <LISTRPM>;
	close (LISTRPM);
	while ($list_entry = shift (@rpmtemplist)) {
		if ($list_entry eq $instrpm."\n") {
			last;
		}
	}
# File created to name the actual rpms that has to be downloaded
# This file is created using rpmlist and will be used by second state of autoscript
	my $entry_to_be_installed=shift(@rpmtemplist);
	chomp($entry_to_be_installed);
	print "$entry_to_be_installed\n";
	if($entry_to_be_installed eq "")
	{
	        open (UPDATELOG, ">>/etc/multiconf/updatelog");
                print UPDATELOG "No updates found.\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");
                my $statstr = "No updates";
                system("rm -f /etc/cron.thirtymins/update_check");
                sendmail ($statstr, "yes");
		`echo 1 > /etc/multiconf/noupdate`;
		return 1;		
		
	}
		
	open(DLDLIST, ">/etc/multiconf/confscripts/rpmdld");
	print DLDLIST $entry_to_be_installed;
	close (DLDLIST);

	
	open(LISTRPM, "/etc/multiconf/confscripts/rpmdld");
	
	$rpmlist[0] = <LISTRPM>;
	close (LISTRPM);
	
} else {
# Multiple lvpngeneral rpms condition
# using the version sort of ls and getting the reverse order, because the latest version should be at the start and that is what we want
	my $lvpn_rpm = `cd $UpdateDir;ls -1vr lvpngeneral-CF* 2>/dev/null | grep -m 1 lvpngeneral-CF | cut -d. -f1`;
	if ($lvpn_rpm) {
		$rpmlist[0] = $lvpn_rpm;
	}
}
		
my $rpm_fail_flag = 1;
foreach $ritem (@rpmlist) {
	chomp($ritem);
	my $rpmfilename = $ritem.".i386.rpm";
	if ( -e "$UpdateDir/$rpmfilename" ) {
    		system("sync");
		my $sizereq=`ls -l $UpdateDir/$rpmfilename|tr -s " "|cut -d " " -f5`;
		my $dsavail = `df / |tr -s " " |cut -d " " -f4 |grep -v vail`;
		chomp $dsavail;
		my $avail = ($dsavail * 1024);
		if ($avail < (3 * $sizereq))
		{
			open (UPDATELOG, ">>/etc/multiconf/updatelog");
			print UPDATELOG "There isnt enough space for installation of $rpmfilename\n";
			print UPDATELOG "Aborting the installation\n";
			close (UPDATELOG);
			sendmail ("RPM List Installation Failed","yes");
			`rm -f $UpdateDir/$rpmfilename`;
    			# flush the filesystem buffers
    			system("sync");
   			 exit(1);
		}
		my $tmp = `rpm --checksig $UpdateDir/$rpmfilename | cut -d: -f2`;
		chomp($tmp);
		if ( $tmp eq " md5 OK") {
			$rpm_fail_flag = 0;
			print "Not downloading $rpmfilename\n";

			next;
		}
		else {
			`rm -f $UpdateDir/$rpmfilename`;
		}	
	}
	#To check if there is enough space for the rpm to be downloaded, if not the installation is aborted
	checkspace("$rpmfilename","$DldDirs[0]");
	push(@DldRPMs,$DldDirs[0]."/".$rpmfilename);
	print "RPM to Download - $rpmfilename\n";
}
	
# if the manual method fails then DldRPMs will be empty (For lvpngeneral alone) but still we need to download every rpm from the ftp directory
if (@DldRPMs || ($rpm_fail_flag == 1 && $lvpn_inst_rpm =~ /not installed/)) {
	print "New rpms from $Host:\n" unless $Quiet;

	# Check for port
	$Port= getservbyname("ftp","tcp");

	unless ($Port) { #Just to be sure
		$Port= 0;
		$Port= 21 if ($Protocol eq "ftp");
	}
	if ( $Host =~ /^(.*):(\d+)$/ ) {
		$Host=$1;
		$Port=$2;
	}

	#Get all new rpms from the dld site
	if ($User) {
		print "Fetching rpms from '$Protocol://$User\@$Host'.\n" if $Debug;
	} else {
		print "Fetching rpms from '$Protocol://$Host'.\n" if $Debug;
		($User, $Pass) = ($DefaultUser, $DefaultPass);
		print "User='$User' Pass='$Pass'.\n" if ($Protocol eq "ftp" and $Debug >1);
	}
	print "Using port: $Port. Passive=$Passive.\n" if ($Debug >1);

	chdir($UpdateDir);

	# The ftp login and connection settings starts here
	unless ($FTPRetry >= 0) {
		$FTPRetry= 0;
	}
	$FTPRetry++;
	while ( ! ($ftp = Net::FTP->new($Host, Debug => $FTPDebug, Passive => $Passive, Firewall => $Firewall, Port => $Port)) ) {
		$FTPRetry--;
		if ($FTPRetry <= 0) {
			print STDERR "Error: Failed to connect to $Host.\n";
			$@ =~ s/Net::FTP/FTP errror/;
			print STDERR "$@\n";
			return 1;
		} else {
			print "Could not connect to $Host. Will try ". $FTPRetry ." more time(s).\n" if $Verbose;
			$@ =~ s/Net::FTP/FTP errror/;
			print "$@\n" if $Debug;
			sleep $FTPWait;
		}
	}

	while ( ! $ftp->login($User,$Pass) ) {
		$FTPRetry--;
		if ($FTPRetry <= 0) {
			print STDERR "Error: Failed to login at $Host: ", $ftp->message;
			return 1;
		} else {
			print "Could not login to $Host. Will try ". $FTPRetry ." more time(s).\n" if $Verbose;
			print "FTP message: ", $ftp->message if $Debug;
			sleep $FTPWait;
		}
	}

	$ftp->binary();
	#if its lvpngeneral then get the remote ftp listing 
	# We will download everything from the remote ftp server
	if (!@DldRPMs) {
		@DldRPMs= Get_RPMs_ftp($ftp,@DldDirs);
	}
  foreach $item (@DldRPMs) {
		print "Item is $item\n";

		unless ($ftp->get($item)) {
			print STDERR "Error: Failed to ftp: ";
			if ($ftp->message !~ /$item/) {
				print STDERR "$item: ";
			}
			if ($ftp->message) {
				print STDERR $ftp->message;
			} else {
				print STDERR "Timeout (?)\n";
			}
			$retval+=1;
		}
		$item = (Split_File($item))[1];
    if (-f $item ) {
			push(@DownloadedRPMs,"$UpdateDir/$item");
    }
	}
	$ftp->quit;
} else {
	print "Found no new rpms at $Host.\n" if $Verbose;
}
return $retval;
}
sub sendmail ()
{
	my ($statusstr, $sendlog) = @_;
	my $logstr = "The system update log file is attached for your reference\n";
	my $logfile = "\/etc\/multiconf\/updatelog";

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

	my $maillist;
	my $mailid;
	my $AdminIdPresent;
	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)
		{
			my $datetoprint = `date +"%Y-%m-%d %H:%M:%S"`;
			chomp ($datetoprint);
			my $hostname = `hostname`;
			chomp ($hostname);
			my $subject = $hostname . " - System Update";
			`echo "System Update on $datetoprint.\n\nStatus: $statusstr.\n$logstr" | mutt -s "$subject" -a $logfile $maillist`;
		}
	}
}


######################
# Main
######################

my $item;

if ( -d $ConfigDir ) {
	if ( ((stat($ConfigDir))[2] >> 1)%2 ) {
		die("Fatal: Configuration directory '$ConfigDir' is world writeable!");
	}
} else {
	print STDERR "Warning: No configuration directory: $ConfigDir\n" if $Warnings;
}

Getopt::Long::Configure('pass_through');
$item= GetOptions('config=s' => \$ConfigFile);
Read_Config($ConfigFile);

if ( $0 =~ /autodld$/) {
	$DoDld=1
}


Getopt::Long::Configure('default');
$item= GetOptions('dld!' => \$DoDld,
	'ftp!' => \$DoDld, #Old syntax
	'url=s' => \$URL,
	'ftpurl=s' => \$URL, #Old syntax
	'dldconfig=s' => \@DldConfig,
	'ftpconfig=s' => \@DldConfig, #Old syntax
	'dldall+' => \$DldAll,
	'ftpall!' => \$DldAll, #Old syntax
 	'dldrecurse!' => \$DldRecurse,
 	'ftprecurse!' => \$DldRecurse, #Old syntax
	'passive!' => \$DefaultPassive,
 	'recurse!' => \$Recurse,
	'updatedir=s' => \$UpdateDir,
	'rpmdir=s' => \$RPMDir,
	'log!' => \$DoLog,
	'logfile=s' => \$LogFile,
	'client' => sub { $DoDld=0; }, #Old Syntax
	'test!' => \$Test,
	'verbose!' => \$Verbose,
	'quiet!' => \$Quiet,
	'warnings!' => \$Warnings,
	'debug=i' => \$Debug,
	'version!' => \$showversion,
	'help!' => \$showhelp );

unless ($item) {
    print STDERR "Try '$0 --help'.\n";
    exit 1;
}

if ($showhelp or $showversion)
{
	print "autoupdate version $Version <Gerald.Teschl\@univie.ac.at>.\n";
    print $USAGE if $showhelp;
    exit 0;
}

print "autoupdate version $Version\n" if $Debug;

$Verbose =0 if $Quiet;
if ($Debug or $Test) {
	$Verbose =1;
	$Quiet =0;
}
$Warnings =1 if $Verbose;

if (@DldConfig or $URL) {
	$DoDld = 1;
}

# Make sure all paths are absolute
$cwd = getcwd();
$cwd = "" if ($cwd eq "/");
$RPMDir= "$cwd/$RPMDir" if ($RPMDir and $RPMDir !~ /^\//);
$UpdateDir= "$cwd/$UpdateDir" if ($UpdateDir and $UpdateDir !~ /^\//);

#Strip_Dir($RPMDir,"1");
Strip_Dir($UpdateDir,"1");

#
# Dld Part
#

my $RetDld = 0;
my $dir;

if ($DoDld) {
  print "\nDoing download part.\n" if $Debug;

	$Passive= $DefaultPassive;
	$dir= "." unless $dir;
	
	my $file;
  unless ($DldConfigDir) {
    $DldConfigDir = $ConfigDir;
  }
  unless (@DldConfig) {
    if ( -d $DldConfigDir ) {
			@DldConfig= glob("$DldConfigDir/*.dld");
		} else {
      print STDERR "Error: No dld configuration directory: $DldConfigDir\n";
 		}
	}
	unless (@DldConfig) {
    print STDERR "Warning: No download configuration files found.\n" if $Warnings;
  }
  foreach $file ( @DldConfig ) {
    if ( Read_Dld_Config($file)==0 ) {
      $RetDld+=Get_Remote_RPMs();
    }
	}
}

my $total = @DownloadedRPMs;
if (@DownloadedRPMs) {
	push(@AllRPMs, @DownloadedRPMs);
	print "Downloaded total of $total rpms.\n" if ($Verbose and $total>1);
  if ($DoLog) {
		my $now= localtime();
		if ($now =~ /^\S+\s+(.*)\s+\S+$/) {
			$now= $1;
		}
		print "Writing log file: $LogFile ($now)\n" if ($Debug);
		if (open(LOGFILE,">>$LogFile")) {
			print LOGFILE "$now: sum: Downloaded total of $total rpm(s).\n" unless $Test;
			for $item (@DownloadedRPMs) {
				$item=(Split_File($item))[1];
				print LOGFILE "$now: dld: $item\n" unless $Test;
			}
			close(LOGFILE);
		} else {
			print STDERR "Error: Could not append to $LogFile: $!\n";
		}
  }

@DownloadedRPMs= ();
}
exit ($RetDld);
