File: //proc/self/root/proc/self/root/scripts.20110531.215904.25158/cPanelRPM.pm
package cPanelRPM;
# cpanel - cPanelRPM.pm Copyright(c) 2010 cPanel, Inc.
# All rights Reserved.
# copyright@cpanel.net http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
use Socket;
use strict;
use Cpanel::HttpTimer;
use Cpanel::Config ();
use Cpanel::StringFunc ();
use Cwd 'chdir';
use IPC::Open3;
my $hassigint = 0;
$SIG{'INT'} = sub {
$hassigint = 1;
print "SIGINT received. Cleaning up and halting operations.\n\n";
};
my $noperl = 1;
my $virtuozzo = -e "/proc/vz/veinfo" ? 1 : 0;
my %CPCONF = Cpanel::Config::loadcpconf();
sub rpmbinversion {
my ($self) = @_;
my $rpmver = `$self->{"rpmbin"} --version`;
chomp($rpmver);
return ($rpmver);
}
sub new {
my ( $distro, $version, $killcache, $rpmbin );
( undef, $distro, $version, $killcache, $rpmbin ) = @_;
my $self = {};
bless($self);
my (@UPDATES);
$self->{'usemirrors'} = 0;
if ( $rpmbin eq "" ) { $rpmbin = 'rpm'; }
$self->{'rpmbin'} = $rpmbin;
print "Using RPM Backend: " . $self->rpmbinversion() . "\n";
if ( $distro eq "" && $version eq "" ) {
if ( -e "/etc/fedora-release" ) {
$distro = 'fedora';
($version) = getversionfromfile('/etc/fedora-release');
}
elsif ( -e "/etc/trustix-release" ) {
$distro = 'trustix';
($version) = getversionfromfile('/etc/trustix-release');
}
elsif ( -e "/etc/whitebox-release" ) {
$distro = 'whitebox';
($version) = getversionfromfile('/etc/whitebox-release');
}
elsif ( -e "/etc/caos-release" ) {
$distro = 'caos';
($version) = getversionfromfile('/etc/caos-release');
}
elsif ( -e "/etc/SuSE-release" ) {
$distro = 'suse';
($version) = getversionfromfile('/etc/SuSE-release');
}
elsif ( -e "/etc/mandrake-release" ) {
$distro = 'mandrake';
($version) = getversionfromfile('/etc/mandrake-release');
}
elsif ( -e "/etc/redhat-release" ) {
$distro = 'redhat';
($version) = getversionfromfile('/etc/redhat-release');
}
else {
die "Your distro is NOT SUPPORTED\n";
}
}
my $priarch = `rpm -q glibc --qf "%{ARCH}"`;
my $myarch;
$self->{"priarch"} = $priarch;
# print "Arch is $priarch\n";
if ( $priarch =~ /686/ ) {
$myarch = '686';
}
elsif ( $priarch =~ /586/ ) { $myarch = '586' }
else {
$myarch = 'x86';
}
$self->{"myarch"} = $myarch;
my ( $mday, $mon, $year );
( undef, undef, undef, $mday, $mon, $year, undef, undef, undef ) = localtime( time() );
$year += 1900;
$mon++;
my ( $ymday, $ymon, $yyear );
( undef, undef, undef, $ymday, $ymon, $yyear, undef, undef, undef ) = localtime( time() - 86400 );
$yyear += 1900;
$ymon++;
my ( $tymday, $tymon, $tyyear );
( undef, undef, undef, $tymday, $tymon, $tyyear, undef, undef, undef ) = localtime( time() - ( 86400 * 2 ) );
$tyyear += 1900;
$tymon++;
$self->{"mday"} = $mday;
$self->{"mon"} = $mon;
$self->{"year"} = $year;
mkdir( "/root/.cpupdates", 0700 );
if ( !-d "/root/.cpupdates" ) {
die "could not create /root/.cpupdates";
}
my $roll = 0;
my @STFS = ( "updates", "provides", "requires" );
foreach my $stf (@STFS) {
if ( !-e "/root/.cpupdates/$mon-$mday-$year.${stf}"
&& -e "/root/.cpupdates/$ymon-$ymday-$yyear.${stf}" ) {
print "cprpmdb: ${stf} rolling from $ymon-$ymday-$yyear\n";
rename( "/root/.cpupdates/$ymon-$ymday-$yyear.${stf}", "/root/.cpupdates/$mon-$mday-$year.${stf}" );
$roll = 1;
}
if ( !-e "/root/.cpupdates/$mon-$mday-$year.${stf}"
&& -e "/root/.cpupdates/$tymon-$tymday-$tyyear.${stf}" ) {
print "cprpmdb: ${stf} rolling from $tymon-$tymday-$tyyear\n";
rename( "/root/.cpupdates/$tymon-$tymday-$tyyear.${stf}", "/root/.cpupdates/$mon-$mday-$year.${stf}" );
$roll = 1;
}
}
opendir( CPUP, "/root/.cpupdates" );
my @FILES = readdir(CPUP);
closedir(CPUP);
foreach my $file (@FILES) {
next if ( $file eq "rpmdb-provides.mtime" );
next if ( $file eq "rpmdb-requires.mtime" );
next if ( $file eq "mirrors.lst" );
next if ( $file eq "pingtimes" );
next if ( $file eq "mirrors.speeds" );
next if ( $file =~ /^rpmup/ );
next if ( $file =~ /^\./ );
if ( $file !~ /^$mon-$mday-$year\./ || $killcache ) {
#print ("Unlinking old cache file /root/.cpupdates/$file\n");
unlink("/root/.cpupdates/$file");
}
}
my ($badf) = 1;
if ( -e "/root/.cpupdates/$mon-$mday-$year.updates" ) {
open( CPUP, "/root/.cpupdates/$mon-$mday-$year.updates" );
while (<CPUP>) {
s/\n//g;
push( @UPDATES, $_ );
}
close(CPUP);
if ( $#UPDATES > 100 ) { $badf = 0; }
}
if (
$distro eq "redhat"
&& ( -e "/usr/bin/wget"
|| -e "/usr/local/bin/wget"
|| -e "/usr/bin/ncftpget"
|| -e "/usr/local/bin/ncftpget" )
) {
$self->{"usemirrors"} = 1;
}
if ( $roll || $badf || ( ( stat("/root/.cpupdates/$mon-$mday-$year.updates") )[9] + 50000 < time() ) ) {
$#UPDATES = 0;
print "Fetching rpm updates list...";
if ( $distro eq "redhat" ) {
httpreqI( 'updates.cpanel.net', "/pub/rpminstall/$distro-$version/updates.${myarch}.v2.db.gz", "/root/.cpupdates/$mon-$mday-$year.updates.gz" );
}
else {
httpreqI( 'updates.cpanel.net', "/pub/rpminstall/$distro-$version/updates.${myarch}.db.gz", "/root/.cpupdates/$mon-$mday-$year.updates.gz" );
}
print "Done\n";
if ( -e "/root/.cpupdates/$mon-$mday-$year.updates.gz" ) {
system( "gzip", "-d", "-f", "/root/.cpupdates/$mon-$mday-$year.updates.gz" );
}
if ( !-e "/root/.cpupdates/$mon-$mday-$year.updates" ) {
die "Cannot fetch rpm updates list";
}
open( CPUP, "/root/.cpupdates/$mon-$mday-$year.updates" );
while (<CPUP>) {
s/\n//g;
push( @UPDATES, $_ );
}
close(CPUP);
}
if ( $roll || ( stat("/root/.cpupdates/$mon-$mday-$year.provides") )[7] < 4096 || ( ( stat("/root/.cpupdates/$mon-$mday-$year.provides") )[9] + 50000 < time() ) ) {
my $compressprog = 'gzip';
print "Fetching rpm provides list...";
if ( -e "/bin/bzip2" || -e "/usr/bin/bzip2" ) {
httpreqI( 'updates.cpanel.net', "/pub/rpminstall/$distro-$version/provides.${myarch}.db.bz2", "/root/.cpupdates/$mon-$mday-$year.provides.bz2" );
if ( -e "/root/.cpupdates/$mon-$mday-$year.provides.bz2" ) {
system( "bzip2", "-d", "-f", "/root/.cpupdates/$mon-$mday-$year.provides.bz2" );
}
}
else {
httpreqI( 'updates.cpanel.net', "/pub/rpminstall/$distro-$version/provides.${myarch}.db.gz", "/root/.cpupdates/$mon-$mday-$year.provides.gz" );
if ( -e "/root/.cpupdates/$mon-$mday-$year.provides.gz" ) {
system( "gzip", "-d", "-f", "/root/.cpupdates/$mon-$mday-$year.provides.gz" );
}
}
print "Done\n";
if ( !-e "/root/.cpupdates/$mon-$mday-$year.provides" ) {
die "Cannot fetch rpm provides list";
}
open( CPUP, "/root/.cpupdates/$mon-$mday-$year.provides" );
open( CPUPI, ">/root/.cpupdates/$mon-$mday-$year.provides.index" );
my $startchar = 0;
while (<CPUP>) {
if ( substr( $_, 0, 2 ) ne $startchar ) {
$startchar = substr( $_, 0, 2 );
my $filepos = ( tell(CPUP) - length($_) );
print CPUPI "$startchar $filepos\n";
}
print CPUP $_ . "\n";
}
close(CPUP);
close(CPUPI);
}
if ( $roll || ( stat("/root/.cpupdates/$mon-$mday-$year.requires") )[7] < 4096 || ( ( stat("/root/.cpupdates/$mon-$mday-$year.requires") )[9] + 50000 < time() ) ) {
print "Fetching rpm requires list...";
httpreqI( 'updates.cpanel.net', "/pub/rpminstall/$distro-$version/requires.${myarch}.db.gz", "/root/.cpupdates/$mon-$mday-$year.requires.gz" );
print "Done\n";
if ( -e "/root/.cpupdates/$mon-$mday-$year.requires.gz" ) {
system( "gzip", "-d", "-f", "/root/.cpupdates/$mon-$mday-$year.requires.gz" );
}
if ( !-e "/root/.cpupdates/$mon-$mday-$year.requires" ) {
die "Cannot fetch rpm requires list";
}
open( CPUP, "/root/.cpupdates/$mon-$mday-$year.requires" );
open( CPUPI, ">/root/.cpupdates/$mon-$mday-$year.requires.index" );
my $startchar = 0;
while (<CPUP>) {
if ( substr( $_, 0, 2 ) ne $startchar ) {
$startchar = substr( $_, 0, 2 );
my $filepos = ( tell(CPUP) - length($_) );
print CPUPI "$startchar $filepos\n";
}
print CPUP $_ . "\n";
}
close(CPUP);
close(CPUPI);
}
$self->getlocalprovides();
$self->getlocalrequires();
my (%UPS);
foreach (@UPDATES) {
my ( $name, $rpmdata ) = split( /=/, $_, 2 );
$UPS{$name} = $rpmdata;
}
my (%DEPS);
$self->{"updates"} = \%UPS;
$self->{"deps"} = \%DEPS;
$self->{'dirtyrequires'} = 0;
return ($self);
}
sub install {
my ( $self, $pkg, $force, $nodeps, $tmpdir, $distup, $nomirrors, $safe, $quiet ) = @_;
my (%UPS) = %{ $self->{"updates"} };
my (%INSTALLED);
my ( @RPMA, @INSPKGS );
if ($nomirrors) { $self->{"usemirrors"} = 0; }
if ( $self->{"dirtyrequires"} ) {
$self->getlocalrequires();
$self->{"dirtyrequires"} = 0;
}
my (@ULLIST);
my $mday = $self->{"mday"};
my $mon = $self->{"mon"};
my $year = $self->{"year"};
open( INSTALLED, "/root/.cpupdates/$mon-$mday-$year.installed" );
while (<INSTALLED>) {
s/\n//g;
my ( $ipkg, $iversion ) = split( /\%/, $_ );
$INSTALLED{$ipkg} = $iversion;
}
close(INSTALLED);
if ( $UPS{$pkg} eq "" ) {
if ( !$safe && !$quiet ) {
print "unknown package $pkg (ok)\n";
}
delete @INSTALLED{ keys %INSTALLED };
return ();
}
else {
my ( $rpmv, $file, $rpmbuilddate, $downdir ) = split( /=/, $UPS{$pkg}, 5 );
my $rpmversion = $rpmv;
$rpmversion = substr( $rpmversion, length($pkg) + 1 );
my $compareopt = cPanelRPM::compareversion( $rpmversion, $INSTALLED{$pkg} );
if ( $compareopt >= 0 && !${force} ) {
print "$pkg: installed version $INSTALLED{$pkg} is up to date, no action needed.\n";
return ();
}
}
$self->resolvedeps( $pkg, 0, 0 );
my (%PKGS) = %{ $self->{"deps"} };
foreach my $pkgs ( sort keys %PKGS ) {
if ( $UPS{$pkgs} eq "" ) {
next();
}
my ( $rpmv, $file, $rpmbuilddate, $downdir, $md5sum ) = split( /=/, $UPS{$pkgs}, 6 );
my $rpmversion = $rpmv;
$rpmversion = substr( $rpmversion, length($pkgs) + 1 );
if ( ( $pkgs =~ /^kernel-/ || $pkgs =~ /^httpd-/ || $pkgs =~ /^k_/ || $pkgs =~ /^cyrus-imapd/ || ( $pkgs =~ /^quota/ && $virtuozzo ) || ( $noperl && $pkgs !~ /^perl-CPAN/ && $pkgs =~ /^perl/ ) ) && $pkgs !~ /^kernel-source/ && $pkgs !~ /^kernel-pcmcia/ ) {
print "$pkgs will be ignored.\n";
}
else {
if ( $force && $pkgs eq $pkg ) {
print "$pkgs: install will be forced to $rpmversion.\n";
}
else {
if ( $INSTALLED{$pkgs} eq $rpmversion ) {
print "$pkgs is current ($INSTALLED{$pkgs}), no action needed.\n";
next;
}
else {
if ( $INSTALLED{$pkgs} eq "" ) {
print "$pkgs: not installed.\n";
}
else {
my $compareopt = cPanelRPM::compareversion( $rpmversion, $INSTALLED{$pkgs}, $distup );
if ( $compareopt >= 0 ) {
print "$pkgs: installed version $INSTALLED{$pkgs} is current ($rpmversion), no action needed.\n";
next;
}
else {
print "$pkgs: current version is $INSTALLED{$pkgs}, will be updated to $rpmversion.\n";
}
}
}
}
}
if ( ( $pkgs =~ /^kernel-/ || $pkgs =~ /^httpd-/ || $pkgs =~ /^k_/ || $pkgs =~ /^cyrus-imapd/ || ( $pkgs =~ /^quota/ && $virtuozzo ) || ( $noperl && $pkgs !~ /^perl-CPAN/ && $pkgs =~ /^perl/ ) ) && $pkgs !~ /^kernel-source/ && $pkgs !~ /^kernel-pcmcia/ ) {
push( @RPMA, "--nodeps" );
}
else {
if ( $pkgs =~ /^iptables/ ) { push( @RPMA, "--nodeps" ); }
if ( $self->{"usemirrors"} && $md5sum ne "" ) {
if ( $self->fetchrpm( "${downdir}/${file}", $md5sum ) ) {
push( @RPMA, "/var/spool/cpupdates/${file}" );
push( @ULLIST, "/var/spool/cpupdates/${file}" );
}
else {
push( @RPMA, "http://updates.cpanel.net" . ${downdir} . "/" . "${file}" );
}
}
else {
push( @RPMA, "http://updates.cpanel.net" . ${downdir} . "/" . "${file}" );
}
}
push( @INSPKGS, $pkgs );
}
if ($hassigint) { die("Terminated at users request"); }
if ( $#RPMA > -1 ) {
if ($force) { push( @RPMA, "--force" ); }
if ($nodeps) { push( @RPMA, "--nodeps" ); }
if ( $tmpdir ne "" ) {
push( @RPMA, "--define", "_tmppath ${tmpdir}", "--define", "tmppath ${tmpdir}" );
}
system( "$self->{'rpmbin'}", "-Uvh", @RPMA );
$self->getlocalprovidesupdate(@INSPKGS);
$self->{'dirtyrequires'} = 1;
}
foreach my $ul (@ULLIST) {
if ( $ul =~ /^\/var\/spool\/cpupdates\// && $ul !~ /\.\./ ) {
unlink($ul);
}
}
delete @INSTALLED{ keys %INSTALLED };
}
sub installedlist {
my ($self) = @_;
my (%INSTALLED);
my $mday = $self->{"mday"};
my $mon = $self->{"mon"};
my $year = $self->{"year"};
open( INSTALLED, "/root/.cpupdates/$mon-$mday-$year.installed" );
while (<INSTALLED>) {
s/\n//g;
my ( $ipkg, $iversion ) = split( /\%/, $_ );
$INSTALLED{$ipkg} = $iversion;
}
close(INSTALLED);
return (%INSTALLED);
}
sub resolvedeps {
my ( $self, $pkg, $level, $passthrough ) = @_;
if ( $passthrough eq "" ) { $passthrough = 0; }
# print ">>> resolvedeps ($level) ($pkg)\n";
if ($hassigint) { die("Terminated at users request"); }
if ( $level eq "0" ) {
delete @{ $self->{"deps"} }{ keys %{ $self->{"deps"} } };
}
my (%INSTALLREQ);
my $usedep = 1;
if ( ( $pkg =~ /^kernel-/ || $pkg =~ /^httpd-/ || $pkg =~ /^k_/ ) && $pkg !~ /^kernel-source/ && $pkg !~ /^kernel-pcmcia/ ) { $usedep = 0; }
if ( $pkg eq "kernel" ) { $usedep = 0; }
if ($usedep) {
${ $self->{"deps"} }{$pkg} = 2;
}
my (@PKGPROVIDES) = $self->getprovides($pkg);
@PKGPROVIDES = $self->stripoutsameprovides( $pkg, \@PKGPROVIDES );
my (@REQDEPPKGS);
if ( $#PKGPROVIDES > -1 ) {
@REQDEPPKGS = $self->getwhatrequires(@PKGPROVIDES);
}
foreach my $reqbydep (@REQDEPPKGS) {
$reqbydep =~ s/-[\w\.]+-[\w\.]+(i.86|noarch)\.rpm$//g;
next if ( $reqbydep eq $pkg );
next if ( Cpanel::StringFunc::ibeginmatch( "$reqbydep", "MySQL-bench" ) );
next if ( ${ $self->{"deps"} }{$reqbydep} >= 1 );
print "Adding InterDependency ${reqbydep} (required by $pkg)\n";
$self->resolvedeps( $reqbydep, ( $level + 1 ), 1 );
foreach my $ndep ( sort keys %{ $self->{"deps"} } ) {
if ( ( $ndep =~ /^kernel-/ || $ndep =~ /^k_/ || $ndep =~ /^httpd-/ ) && $ndep !~ /^kernel-source/ && $ndep !~ /^kernel-pcmcia/ ) { next; }
if ( $ndep eq "kernel" ) { next; }
if ( ${ $self->{"deps"} }{$ndep} == 1 ) {
$self->resolvedeps( $ndep, ( $level + 1 ), 0 );
}
}
}
my $mday = $self->{"mday"};
my $mon = $self->{"mon"};
my $year = $self->{"year"};
my $pkgidx = substr( $pkg, 0, 2 );
my $seekpoint;
open( REQIDX, "/root/.cpupdates/$mon-$mday-$year.requires.index" );
while (<REQIDX>) {
if ( substr( $_, 0, length($pkgidx) + 1 ) eq $pkgidx . " " ) {
/\s(\d+)$/;
close(REQIDX);
$seekpoint = $1;
last;
}
}
close(REQIDX);
open( REQ, "/root/.cpupdates/$mon-$mday-$year.requires" );
seek( REQ, $seekpoint, 0 );
while (<REQ>) {
if ( substr( $_, 0, length($pkg) + 1 ) eq $pkg . "%" ) {
my ($requires);
( undef, $requires ) = split( /\%/, $_ );
chomp($requires);
my (@REQLIST) = split( /\,/, $requires );
foreach my $req (@REQLIST) {
my ( $item, $version );
if ( $req =~ /\>\=/ ) {
( $item, $version ) = split( /\>\=/, $req );
$item =~ s/^\s*|\s*$//g;
$version =~ s/^\s*|\s*$//g;
$version = $version . "|>=";
}
elsif ( $req =~ /\<\=/ ) {
( $item, $version ) = split( /\<\=/, $req );
$item =~ s/^\s*|\s*$//g;
$version =~ s/^\s*|\s*$//g;
$version = $version . "|<=";
}
elsif ( $req =~ /\>/ ) {
( $item, $version ) = split( /\>/, $req );
$item =~ s/^\s*|\s*$//g;
$version =~ s/^\s*|\s*$//g;
$version = $version . "|>";
}
elsif ( $req =~ /\</ ) {
( $item, $version ) = split( /\</, $req );
$item =~ s/^\s*|\s*$//g;
$version =~ s/^\s*|\s*$//g;
$version = $version . "|<";
}
else {
( $item, $version ) = split( /\=/, $req );
$item =~ s/^\s*|\s*$//g;
$version =~ s/^\s*|\s*$//g;
$version = $version . "|=";
}
next if ( $item =~ /^rpmlib/ );
next if ( $item =~ /^netcfg$/ );
if ( $version eq "|=" ) { $version = "-1"; }
if ( $version eq "|<" ) { $version = "-1"; }
if ( $version eq "|>" ) { $version = "-1"; }
if ( $version eq "|>=" ) { $version = "-1"; }
if ( $version eq "|<=" ) { $version = "-1"; }
my $installver = $version;
my $preinstallver = $INSTALLREQ{$item};
if ( $installver =~ /:/ ) { ( undef, $installver ) = split( /:/, $installver ); }
if ( $installver =~ /\|/ ) { ( $installver, undef ) = split( /\|/, $installver ); }
if ( $preinstallver =~ /:/ ) { ( undef, $preinstallver ) = split( /:/, $preinstallver ); }
if ( $preinstallver =~ /\|/ ) { ( $preinstallver, undef ) = split( /\|/, $preinstallver ); }
if ( $INSTALLREQ{$item} eq "" || compareversion( $installver, $preinstallver ) >= 0 ) {
$INSTALLREQ{$item} = $version;
}
}
close(REQ);
last;
}
}
close(REQ);
my %SEEKPOINTS;
open( LPROIDX, "/root/.cpupdates/$mon-$mday-$year.locprovides.index" );
while (<LPROIDX>) {
foreach my $item ( sort keys %INSTALLREQ ) {
my $itemidx = substr( $item, 0, 2 );
if ( substr( $_, 0, length($itemidx) + 1 ) eq $itemidx . " " ) {
/\s(\d+)$/;
$SEEKPOINTS{$item} = $1;
}
}
}
close(LPROIDX);
open( LPRO, "/root/.cpupdates/$mon-$mday-$year.locprovides" );
foreach my $item ( sort keys %INSTALLREQ ) {
seek( LPRO, $SEEKPOINTS{$item}, 0 );
while (<LPRO>) {
if ( substr( $_, 0, length($item) + 1 ) eq $item . "%" ) {
my ( $version, $ppkg );
( undef, $ppkg, $version ) = split( /\%/, $_, 3 );
$ppkg =~ s/\n//g;
if ( ( ${ $self->{"deps"} }{$ppkg} >= 1 ) && $item eq $ppkg ) { next; } #installed version's cannot
#satisify deps since they
#will be removed when they are
#upgraded
if ( ( ${ $self->{"deps"} }{$ppkg} >= 1 ) && $pkg eq $ppkg ) { next; } #installed version's cannot
#satisify deps since they
#will be removed when they are
#upgraded
my $sat = 0;
if ( $INSTALLREQ{$item} =~ /\>/ || $INSTALLREQ{$item} =~ /\</ || $INSTALLREQ{$item} =~ /\=/ ) {
my $pkgv = ${version};
if ( $pkgv =~ /:/ ) { ( undef, $pkgv ) = split( /:/, $pkgv ); }
$pkgv =~ s/\n//g;
my ( $requiredver, $requiredop ) = split( /\|/, $INSTALLREQ{$item} );
if ( $requiredver =~ /:/ ) { ( undef, $requiredver ) = split( /:/, $requiredver ); }
my $compareopt = compareversion( $requiredver, $pkgv );
if ( $requiredop eq "=" && $compareopt == 0 ) {
delete $INSTALLREQ{$item};
$sat = 1;
}
if ( $requiredop eq ">" && $compareopt == 1 ) {
delete $INSTALLREQ{$item};
$sat = 1;
}
if ( $requiredop eq "<" && $compareopt == -1 ) {
delete $INSTALLREQ{$item};
$sat = 1;
}
if ( $requiredop eq ">=" && ( $compareopt == 1 || $compareopt == 0 ) ) {
delete $INSTALLREQ{$item};
$sat = 1;
}
if ( $requiredop eq "<=" && ( $compareopt == -1 || $compareopt == 0 ) ) {
delete $INSTALLREQ{$item};
$sat = 1;
}
}
else {
delete $INSTALLREQ{$item};
$sat = 1;
}
if ( !$sat ) { next; }
}
}
}
close(LPRO);
delete @SEEKPOINTS{ keys %SEEKPOINTS };
my %SEEKPOINTS;
open( PROIDX, "/root/.cpupdates/$mon-$mday-$year.provides.index" );
while (<PROIDX>) {
foreach my $item ( sort keys %INSTALLREQ ) {
my $itemidx = substr( $item, 0, 2 );
if ( $SEEKPOINTS{$itemidx} eq "" && substr( $_, 0, length($itemidx) + 1 ) eq $itemidx . " " ) {
/\s(\d+)$/;
$SEEKPOINTS{$itemidx} = $1;
}
}
}
close(PROIDX);
if ( tell(PRO) == -1 ) {
open( PRO, "/root/.cpupdates/$mon-$mday-$year.provides" );
}
foreach my $item ( sort keys %INSTALLREQ ) {
my %DEPLIST;
my $itemidx = substr( $item, 0, 2 );
seek( PRO, $SEEKPOINTS{$itemidx}, 0 );
while (<PRO>) {
my $founddep = 0;
if ( substr( $_, 0, length($item) + 1 ) eq $item . "%" ) {
$founddep = 1;
s/\n//g;
my ( $version, $ppkg );
( undef, $ppkg, $version ) = split( /\%/, $_, 3 );
$DEPLIST{$ppkg} = $version;
last; #stop searching as we found something that provides it
}
elsif ( $founddep == 1 ) {
last;
}
}
#the new package provides the item we are looking for
#basiclly it includes what it requires
if ( $DEPLIST{$pkg} ne "" ) {
delete $INSTALLREQ{$item};
}
else {
#we might have a package that provide it so lets check and resolve the
#deps for that pacakge
foreach my $ppkg ( keys %DEPLIST ) {
next if ( Cpanel::StringFunc::ibeginmatch( $ppkg, "MySQL-bench" ) );
my $version = $DEPLIST{$ppkg};
my $sat = 0;
if ( $INSTALLREQ{$item} =~ /\>/ || $INSTALLREQ{$item} =~ /\</ || $INSTALLREQ{$item} =~ /\=/ ) {
my $pkgv = ${version};
if ( $pkgv =~ /:/ ) { ( undef, $pkgv ) = split( /:/, $pkgv ); }
$pkgv =~ s/\n//g;
my ( $requiredver, $requiredop ) = split( /\|/, $INSTALLREQ{$item} );
if ( $requiredver =~ /:/ ) { ( undef, $requiredver ) = split( /:/, $requiredver ); }
my $compareopt = compareversion( $requiredver, $pkgv );
if ( $pkgv == -1 ) {
delete $INSTALLREQ{$item};
$sat = 1;
}
else {
if ( $requiredop eq "=" && $compareopt == 0 ) {
delete $INSTALLREQ{$item};
$sat = 1;
}
if ( $requiredop eq ">" && $compareopt == 1 ) {
delete $INSTALLREQ{$item};
$sat = 1;
}
if ( $requiredop eq "<" && $compareopt == -1 ) {
delete $INSTALLREQ{$item};
$sat = 1;
}
if ( $requiredop eq ">=" && ( $compareopt == 1 || $compareopt == 0 ) ) {
delete $INSTALLREQ{$item};
$sat = 1;
}
if ( $requiredop eq "<=" && ( $compareopt == -1 || $compareopt == 0 ) ) {
delete $INSTALLREQ{$item};
$sat = 1;
}
}
}
else {
delete $INSTALLREQ{$item};
$sat = 1;
}
if ( !$sat ) { next; }
if ( !( ${ $self->{"deps"} }{$ppkg} >= 1 ) ) {
print "Adding Dependency ${ppkg} (required by $pkg)\n";
$self->resolvedeps( $ppkg, ( $level + 1 ), 0 );
foreach my $ndep ( sort keys %{ $self->{"deps"} } ) {
if ( ( $ndep eq "kernel" || $ndep =~ /^kernel-/ || $ndep =~ /^k_/ || $ndep =~ /httpd-/ ) && $ndep !~ /^kernel-source/ && $ndep !~ /^kernel-pcmcia/ ) { next; }
if ( ${ $self->{"deps"} }{$ndep} == 1 ) {
$self->resolvedeps( $ndep, ( $level + 1 ), 0 );
}
}
}
}
}
delete @DEPLIST{ keys %DEPLIST };
}
if ( $level == 0 ) {
close(PRO);
}
if ( scalar keys %INSTALLREQ > 0 ) {
my $unresdeath = 0;
foreach my $unresdep ( keys %INSTALLREQ ) {
if ( ( $unresdep eq "kernel" || $unresdep =~ /^kernel-/ || $unresdep =~ /^k_/ || $unresdep =~ /^httpd-/ ) && $unresdep !~ /^kernel-source/ && $unresdep !~ /^kernel-pcmcia/ ) { next; }
print "Could not find $unresdep ($INSTALLREQ{$unresdep}) for $pkg\n";
$unresdeath = 1;
}
if ($unresdeath) {
die "[resolvedeps ($level)]";
}
}
delete @SEEKPOINTS{ keys %SEEKPOINTS };
}
sub isinarray {
my ( $pkg, $deps ) = @_;
my (@DEPS) = @{$deps};
foreach (@DEPS) {
if ( $_ eq $pkg ) { return 1; }
}
return 0;
}
sub getlocalprovides {
my ( $self, $nocache ) = @_;
open( CPUP, "/root/.cpupdates/rpmdb-provides.mtime" );
my $rpmdbmtime = <CPUP>;
close(CPUP);
my $currentrpmmtime;
if ( -e "/var/lib/rpm/Provideversion" ) {
$currentrpmmtime = ( stat("/var/lib/rpm/Provideversion") )[9];
}
else {
$currentrpmmtime = ( stat("/var/lib/rpm/fileindex.rpm") )[9];
}
if ( $currentrpmmtime ne $rpmdbmtime ) {
$nocache = 1;
}
open( CPUP, ">/root/.cpupdates/rpmdb-provides.mtime" );
print CPUP $currentrpmmtime;
close(CPUP);
my $mday = $self->{"mday"};
my $mon = $self->{"mon"};
my $year = $self->{"year"};
if ( ( stat("/root/.cpupdates/$mon-$mday-$year.locprovides") )[7] < 4096
|| ( stat("/root/.cpupdates/$mon-$mday-$year.installed") )[7] < 200
|| $nocache ) {
print "Building local rpm provides list...";
open( INSTALLED, ">/root/.cpupdates/$mon-$mday-$year.installed" );
my (%PROL);
my (%PROD);
open( RPM, "rpm -qa --queryformat \"\t%{NAME}\\%%{VERSION}-%{RELEASE}\\%[%{FILENAMES},]\n\" --provides|" );
my ($pkg);
while (<RPM>) {
chomp();
if (/^\t/) {
s/^\t//g;
my ( $pkgversion, $provides );
( $pkg, $pkgversion, $provides ) = split( /\%/, $_, 3 );
print INSTALLED "${pkg}%${pkgversion}\n";
my (@PROLIST) = split( /\,/, $provides );
foreach my $pro (@PROLIST) {
next if ( $pro eq "" );
my $item = $pro;
my $version;
if ( $item =~ /=/ ) {
( $item, $version ) = split( /\=/, $item );
$item =~ s/^\s*|\s*$//g;
$version =~ s/^\s*|\s*$//g;
}
else {
$version = "-1";
}
$PROL{$item}{$pkg} = $version;
}
}
else {
my $item = $_;
$item =~ s/^\s*|\s*$//g;
my $version;
if ( $item =~ /=/ ) {
( $item, $version ) = split( /\=/, $item );
$item =~ s/^\s*|\s*$//g;
$version =~ s/^\s*|\s*$//g;
}
else {
$version = "-1";
}
$PROL{$item}{$pkg} = $version;
$PROD{$pkg}{$item} = $version;
}
}
open( CPUP, ">/root/.cpupdates/$mon-$mday-$year.locprovides" );
open( CPUPI, ">/root/.cpupdates/$mon-$mday-$year.locprovides.index" );
my $startchar = 0;
foreach my $item ( sort keys %PROL ) {
foreach my $package ( sort keys %{ $PROL{$item} } ) {
if ( substr( $item, 0, 2 ) ne $startchar ) {
$startchar = substr( $item, 0, 2 );
my $filepos = tell(CPUP);
print CPUPI "$startchar $filepos\n";
}
print CPUP ${item} . "%" . $package . "%" . $PROL{$item}{$package} . "\n";
}
}
close(INSTALLED);
close(CPUPI);
close(CPUP);
open( CPUP, ">/root/.cpupdates/$mon-$mday-$year.locproviders" );
open( CPUPI, ">/root/.cpupdates/$mon-$mday-$year.locproviders.index" );
my $startchar = 0;
foreach my $package ( sort keys %PROD ) {
foreach my $item ( sort keys %{ $PROD{$package} } ) {
if ( substr( $item, 0, 2 ) ne $startchar ) {
$startchar = substr( $item, 0, 2 );
my $filepos = tell(CPUP);
print CPUPI "$startchar $filepos\n";
}
print CPUP ${package} . "%" . ${item} . "%" . $PROD{$package}{$item} . "\n";
}
}
close(CPUP);
close(CPUPI);
delete @PROL{ keys %PROL };
delete @PROD{ keys %PROD };
print "Done\n";
}
}
sub getlocalrequires {
my ( $self, $nocache ) = @_;
open( CPUP, "/root/.cpupdates/rpmdb-requires.mtime" );
my $rpmdbmtime = <CPUP>;
close(CPUP);
my $currentrpmmtime;
if ( -e "/var/lib/rpm/Provideversion" ) {
$currentrpmmtime = ( stat("/var/lib/rpm/Provideversion") )[9];
}
else {
$currentrpmmtime = ( stat("/var/lib/rpm/fileindex.rpm") )[9];
}
if ( $currentrpmmtime ne $rpmdbmtime ) {
$nocache = 1;
}
open( CPUP, ">/root/.cpupdates/rpmdb-requires.mtime" );
print CPUP $currentrpmmtime;
close(CPUP);
my $mday = $self->{"mday"};
my $mon = $self->{"mon"};
my $year = $self->{"year"};
if ( ( stat("/root/.cpupdates/$mon-$mday-$year.locrequires") )[7] < 4096
|| $nocache ) {
print "Building local rpm requires list...";
my (%PROL);
my (%PROD);
open( RPM, "rpm -qa --queryformat \"%{NAME}\\%%{VERSION}-%{RELEASE}\\%[%{REQUIRENAME}=%{REQUIREVERSION},]\n\"|" );
my ($pkg);
while (<RPM>) {
chomp();
my ( $pkgversion, $requires );
( $pkg, $pkgversion, $requires ) = split( /\%/, $_, 3 );
my (@REQLIST) = split( /\,/, $requires );
foreach my $req (@REQLIST) {
next if ( $req eq "" );
my ( $item, $version ) = split( /\=/, $req );
$PROL{$item}{$pkg} = 1;
}
}
close(RPM);
open( CPUP, ">/root/.cpupdates/$mon-$mday-$year.locrequires" );
open( CPUPI, ">/root/.cpupdates/$mon-$mday-$year.locrequires.index" );
my $startchar = 0;
foreach my $item ( sort keys %PROL ) {
foreach my $package ( sort keys %{ $PROL{$item} } ) {
if ( substr( $item, 0, 2 ) ne $startchar ) {
$startchar = substr( $item, 0, 2 );
my $filepos = tell(CPUP);
print CPUPI "$startchar $filepos\n";
}
print CPUP ${item} . "%" . $package . "\n";
}
}
close(INSTALLED);
close(CPUPI);
close(CPUP);
delete @PROL{ keys %PROL };
print "Done\n";
}
}
sub getlocalprovidesupdate {
my ( $self, @NEWPKGS ) = @_;
my ( %INSTALLED, %LOCPRO );
my $currentrpmmtime;
if ( -e "/var/lib/rpm/Provideversion" ) {
$currentrpmmtime = ( stat("/var/lib/rpm/Provideversion") )[9];
}
else {
$currentrpmmtime = ( stat("/var/lib/rpm/fileindex.rpm") )[9];
}
open( CPUP, ">/root/.cpupdates/rpmdb-provides.mtime" );
print CPUP $currentrpmmtime;
close(CPUP);
my $mday = $self->{"mday"};
my $mon = $self->{"mon"};
my $year = $self->{"year"};
my (%PROL);
my (%PROD);
open( CPUP, "/root/.cpupdates/$mon-$mday-$year.locprovides" );
while (<CPUP>) {
s/\n//g;
foreach my $pkg (@NEWPKGS) {
next if ( $pkg eq "kernel" );
next if ( ( $pkg =~ /^kernel-/ || $pkg =~ /^k_/ || $pkg =~ /^httpd-/ ) && $pkg !~ /^kernel-source/ && $pkg !~ /^kernel-pcmcia/ );
if ( substr( $_, -1 * length("%${pkg}") ) eq "%${pkg}" ) {
next;
}
}
my ( $item, $pkg, $version ) = split( /\%/, $_, 3 );
$PROL{$item}{$pkg} = $version;
}
close(CPUP);
open( CPUP, "/root/.cpupdates/$mon-$mday-$year.locproviders" );
while (<CPUP>) {
s/\n//g;
foreach my $pkg (@NEWPKGS) {
if ( substr( $_, length("%${pkg}") ) eq "${pkg}%" ) {
next;
}
}
my ( $pkg, $item, $version ) = split( /\%/, $_, 3 );
$PROD{$pkg}{$item} = $version;
}
close(CPUP);
print "Rebuilding local rpm provides list...";
open( INSTALLED, ">>/root/.cpupdates/$mon-$mday-$year.installed" );
foreach my $pkg (@NEWPKGS) {
print "..$pkg..";
my $pkginfo = `rpm -q --queryformat \"\t%{NAME}\\%%{VERSION}-%{RELEASE}\\%[%{FILENAMES},]\n\" --provides ${pkg}`;
if ( $pkginfo =~ /is not installed/ ) { next; }
s/\n//g;
my (@PKGL) = split( /\n/, $pkginfo );
my $pkgq = shift(@PKGL);
$pkgq =~ s/^\t//g;
my ( $pkg, $pkgversion, $provides ) = split( /\%/, $pkgq, 3 );
print INSTALLED "${pkg}%${pkgversion}\n";
my (@PROLIST) = split( /\,/, $provides );
foreach my $pro (@PROLIST) {
next if ( $pro eq "" );
my $item = $pro;
$item =~ s/^\s*|\s*$//g;
my $version;
if ( $item =~ /=/ ) {
( $item, $version ) = split( /\=/, $item );
$item =~ s/^\s*|\s*$//g;
$version =~ s/^\s*|\s*$//g;
}
else {
$version = "-1";
}
$PROL{$item}{$pkg} = $version;
}
foreach my $pro (@PKGL) {
next if ( $pro eq "" );
my $item = $pro;
$item =~ s/^\s*|\s*$//g;
my $version;
if ( $item =~ /=/ ) {
( $item, $version ) = split( /\=/, $item );
$item =~ s/^\s*|\s*$//g;
$version =~ s/^\s*|\s*$//g;
}
else {
$version = "-1";
}
$PROL{$item}{$pkg} = $version;
$PROD{$pkg}{$item} = $version;
}
}
print "Done\n";
open( CPUP, ">/root/.cpupdates/$mon-$mday-$year.locprovides" );
open( CPUPI, ">/root/.cpupdates/$mon-$mday-$year.locprovides.index" );
my $startchar = 0;
foreach my $item ( sort keys %PROL ) {
foreach my $package ( sort keys %{ $PROL{$item} } ) {
if ( substr( $item, 0, 2 ) ne $startchar ) {
$startchar = substr( $item, 0, 2 );
my $filepos = tell(CPUP);
print CPUPI "$startchar $filepos\n";
}
print CPUP ${item} . "%" . $package . "%" . $PROL{$item}{$package} . "\n";
}
}
close(CPUP);
close(CPUPI);
close(INSTALLED);
open( CPUP, ">/root/.cpupdates/$mon-$mday-$year.locproviders" );
open( CPUPI, ">/root/.cpupdates/$mon-$mday-$year.locproviders.index" );
my $startchar = 0;
foreach my $package ( sort keys %PROD ) {
foreach my $item ( sort keys %{ $PROD{$package} } ) {
if ( substr( $item, 0, 2 ) ne $startchar ) {
$startchar = substr( $item, 0, 2 );
my $filepos = tell(CPUP);
print CPUPI "$startchar $filepos\n";
}
print CPUP ${package} . "%" . ${item} . "%" . $PROD{$package}{$item} . "\n";
}
}
close(CPUP);
close(CPUPI);
delete @PROL{ keys %PROL };
delete @PROD{ keys %PROD };
}
sub getversionfromfile {
my ($file) = @_;
my ( $line, $version );
open( FILE, $file );
chomp( $line = <FILE> );
if ( $line =~ /(\d+\.\d+)/ ) {
$version = $1;
}
elsif ( $line =~ /(\d+)/ ) {
$version = $1;
}
close(FILE);
if ( $version eq "" ) { die "Can't find distro version"; }
return $version;
}
sub httpreqI {
my ( $host, $url, $outfile ) = @_;
my $trueoutfile = $outfile;
$trueoutfile =~ s/\.(bz2|gz)$//g;
my $md5sum = httpreq( $host, $url . ".md5" );
my $localmd5sum = getmd5sum($trueoutfile);
$md5sum =~ s/[\n\r\s\t]*//g;
$localmd5sum =~ s/[\n\r\s\t]*//g;
if ( $localmd5sum eq $md5sum ) {
system( "touch", $trueoutfile );
return ();
}
print "cached ${trueoutfile} is up to date...";
httpreq( $host, $url, $outfile );
}
sub httpreq {
my ($page);
my ( $host, $url, $outfile ) = @_;
if ( $outfile ne "" ) {
open( HTTPREQF, ">$outfile" );
}
eval {
$SIG{'PIPE'} = $SIG{'ALRM'} = sub {
print "Unable to retrieve file\n";
die;
};
alarm(30);
my $proto = getprotobyname('tcp');
socket( Socket_Handle, AF_INET, SOCK_STREAM, $proto );
my $iaddr = inet_aton("$host");
my $port = getservbyname( 'http', 'tcp' );
my $sin = sockaddr_in( $port, $iaddr );
connect( Socket_Handle, $sin );
send Socket_Handle, "GET $url HTTP/1.0\r\nHost: $host\r\n\r\n", 0;
my $inheader = 1;
while (<Socket_Handle>) {
alarm(20);
if ( !$inheader ) {
if ( $outfile ne "" ) { print HTTPREQF; }
else { $page .= $_; }
}
if ( $inheader && (/^HTTP\/\d+\.\d+ (\d+)/) ) {
if ( $1 eq "404" || $1 eq "500" || $1 eq "301" ) {
print "Error $1 while fetching url http://$host/$url\n";
print "This could indicate you have not properly configured an update source:\n";
print "To select an update source create a file in /var/cpanel called use[sourcename]\n";
print "For example:\n";
print "\t/var/cpanel/useurpmi - URPMI (Mandrake,Mandriva)\n";
print "\t/var/cpanel/useyum - Yum (CloudLinux,CentOS,Fedora)\n";
print "\t/var/cpanel/useup2date - U2pdate (RHEL)\n";
print "\t/var/cpanel/useswup - SWUP (Trustix)\n";
print "\t/var/cpanel/userug - Rug (SuSE)\n";
print "\t/var/cpanel/useapt - Apt-Get (Debian)\n";
print "\t/var/cpanel/useemerge - Portage (Gentoo)\n";
return ();
}
}
if ( $inheader && ( /^\n$/ || /^\r\n$/ || /^$/ ) ) { $inheader = 0; }
}
alarm(0);
};
if ( $outfile ne "" ) {
open(HTTPREQF);
return ();
}
return ($page);
}
sub compareversion {
my ( $wants, $has, $ignorebuild ) = @_;
#fedora-legacy for breaking the standard
$wants =~ s/\.legacy$//g;
$has =~ s/\.legacy$//g;
#0 if match =
#-1 if less
#1 if greater
if ( $wants eq $has ) { return (0); }
my (@WANTSVERR) = split( /-/, $wants );
my (@HASVERR) = split( /-/, $has );
my ( $wantsrel, $hasrel );
if ( $#WANTSVERR == 0 ) {
$wantsrel = 0;
}
else {
$wantsrel = pop(@WANTSVERR);
}
if ( $#HASVERR == 0 ) {
$hasrel = 0;
}
else {
$hasrel = pop(@HASVERR);
}
my ($wantsver) = join( "-", @WANTSVERR );
my ($hasver) = join( "-", @HASVERR );
if ( $wantsrel eq "" ) { $wantsrel = 0; }
if ( $hasrel eq "" ) { $hasrel = 0; }
if ( $wantsver eq $hasver && $wantsrel eq $hasrel ) { return (0); }
my @WANTSVERS = split( /\./, $wantsver );
my @HASVERS = split( /\./, $hasver );
while ( $#WANTSVERS < $#HASVERS ) {
push( @WANTSVERS, "0" );
}
while ( $#WANTSVERS > $#HASVERS ) {
push( @HASVERS, "0" );
}
for ( my $i = 0; $i <= $#WANTSVERS; $i++ ) {
next if ( $HASVERS[$i] eq "0" && $i eq "0" && $WANTSVERS[$i] eq "0" );
if ( $HASVERS[$i] =~ /rc/ && int( $WANTSVERS[$i] ) == int( $HASVERS[$i] ) ) {
if ( $WANTSVERS[$i] !~ /rc/ ) { return (-1); }
if ( $WANTSVERS[$i] =~ /rc/ ) {
$WANTSVERS[$i] =~ /(\d+)$/;
my $rcw = $1;
$HASVERS[$i] =~ /(\d+)$/;
my $rch = $1;
if ( int($rcw) > int($rch) ) {
return (-1);
}
if ( int($rcw) < int($rch) ) {
return (1);
}
}
}
#perl 5.8.0 is better then 5.00404
if ( $i > 0 && $WANTSVERS[$i] =~ /^00/ ) { $WANTSVERS[$i] = 0; }
if ( $i > 0 && $HASVERS[$i] =~ /^00/ ) { $HASVERS[$i] = 0; }
if ( $WANTSVERS[$i] =~ /\D$/ && $HASVERS[$i] =~ /\D$/ && int( $WANTSVERS[$i] ) == int( $HASVERS[$i] ) ) {
$WANTSVERS[$i] =~ /(\D)$/;
my $whatchar = $1;
$HASVERS[$i] =~ /(\D)$/;
my $haschar = $1;
if ( ord($whatchar) > ord($haschar) ) { return (-1); }
if ( ord($whatchar) < ord($haschar) ) { return (1); }
}
if ( int( $WANTSVERS[$i] ) > int( $HASVERS[$i] ) ) {
return (-1);
}
if ( int( $WANTSVERS[$i] ) < int( $HASVERS[$i] ) ) {
return (1);
}
}
if ($ignorebuild) { return (-1); }
#we get here if the version are the same
my @WANTSRELS = split( /\./, $wantsrel );
my @HASRELS = split( /\./, $hasrel );
while ( $#WANTSRELS < $#HASRELS ) {
push( @WANTSRELS, "0" );
}
while ( $#WANTSRELS > $#HASRELS ) {
push( @HASRELS, "0" );
}
for ( my $i = 0; $i <= $#WANTSRELS; $i++ ) {
if ( int( $WANTSRELS[$i] ) > int( $HASRELS[$i] ) ) {
return (-1);
}
if ( int( $WANTSRELS[$i] ) < int( $HASRELS[$i] ) ) {
return (1);
}
}
#we get here if the releases are the same
return (0);
}
sub whatprovides {
my ( $self, $item ) = @_;
my $mday = $self->{"mday"};
my $mon = $self->{"mon"};
my $year = $self->{"year"};
if ( tell(PRO) == -1 ) {
open( PRO, "/root/.cpupdates/$mon-$mday-$year.provides" );
}
while (<PRO>) {
my $founddep = 0;
my ( $fitem, $ppkg, $version ) = split( /\%/, $_, 3 );
if ( $fitem =~ /${item}$/ ) {
close(PRO);
return ($ppkg);
last;
}
}
close(PRO);
}
sub getprovides {
my ( $self, $item ) = @_;
my (@PROVIDES);
my ($seekpoint) = 0;
my $mday = $self->{"mday"};
my $mon = $self->{"mon"};
my $year = $self->{"year"};
open( LPROIDX, "/root/.cpupdates/$mon-$mday-$year.locproviders.index" );
while (<LPROIDX>) {
my $itemidx = substr( $item, 0, 2 );
if ( substr( $_, 0, length($itemidx) + 1 ) eq $itemidx . " " ) {
/\s(\d+)$/;
$seekpoint = $1;
last;
}
}
close(LPROIDX);
my $founditem = 0;
open( LPRO, "/root/.cpupdates/$mon-$mday-$year.locproviders" );
seek( LPRO, $seekpoint, 0 );
while (<LPRO>) {
if ( substr( $_, 0, length($item) + 1 ) eq $item . "%" ) {
chomp();
$founditem = 1;
my ( $version, $item );
( undef, $item, $version ) = split( /\%/, $_, 3 );
push( @PROVIDES, "${item}" );
}
elsif ($founditem) {
last;
}
}
close(LPRO);
return (@PROVIDES);
}
sub stripoutsameprovides {
my ( $self, $pkg, $locp ) = @_;
my (@PROVIDES) = @{$locp};
my ($seekpoint) = 0;
my $mday = $self->{"mday"};
my $mon = $self->{"mon"};
my $year = $self->{"year"};
my %LOCPROVIDES;
foreach my $provide (@PROVIDES) {
$LOCPROVIDES{$provide} = 1;
}
undef @PROVIDES;
my %SEEKPOINTS;
open( PROIDX, "/root/.cpupdates/$mon-$mday-$year.provides.index" );
while (<PROIDX>) {
foreach my $item ( keys %LOCPROVIDES ) {
my $itemidx = substr( $item, 0, 2 );
if ( $SEEKPOINTS{$itemidx} eq "" && substr( $_, 0, length($itemidx) + 1 ) eq $itemidx . " " ) {
/\s(\d+)$/;
$SEEKPOINTS{$itemidx} = $1;
}
}
}
close(PROIDX);
if ( tell(PRO) == -1 ) {
open( PRO, "/root/.cpupdates/$mon-$mday-$year.provides" );
}
foreach my $item ( keys %LOCPROVIDES ) {
next if ( $item eq $pkg );
my $itemidx = substr( $item, 0, 2 );
seek( PRO, $SEEKPOINTS{$itemidx}, 0 );
while (<PRO>) {
if ( substr( $_, 0, length($item) + 1 ) eq $item . "%" ) {
s/\n//g;
my ( $version, $ppkg );
( undef, $ppkg, $version ) = split( /\%/, $_, 3 );
if ( $ppkg eq $pkg ) { delete $LOCPROVIDES{$item}; }
last; #stop searching as we found something that provides it
}
}
}
delete @SEEKPOINTS{ keys %SEEKPOINTS };
foreach my $provide ( keys %LOCPROVIDES ) {
push( @PROVIDES, $provide );
}
delete @LOCPROVIDES{ keys %LOCPROVIDES };
return (@PROVIDES);
}
sub getwhatrequires {
my ( $self, @REQITEMS ) = @_;
my (@REQDPKGS);
my $mday = $self->{"mday"};
my $mon = $self->{"mon"};
my $year = $self->{"year"};
my %SEEKPOINTS;
open( LREQIDX, "/root/.cpupdates/$mon-$mday-$year.locrequires.index" );
while (<LREQIDX>) {
foreach my $item ( sort @REQITEMS ) {
my $itemidx = substr( $item, 0, 2 );
if ( substr( $_, 0, length($itemidx) + 1 ) eq $itemidx . " " ) {
/\s(\d+)$/;
$SEEKPOINTS{$item} = $1;
}
}
}
close(LREQIDX);
open( LREQ, "/root/.cpupdates/$mon-$mday-$year.locrequires" );
foreach my $item ( sort @REQITEMS ) {
seek( LREQ, $SEEKPOINTS{$item}, 0 );
while (<LREQ>) {
if ( substr( $_, 0, length($item) + 1 ) eq $item . "%" ) {
my ($reqpkg);
chomp();
( undef, $reqpkg ) = split( /\%/, $_ );
push( @REQDPKGS, $reqpkg );
}
}
}
close(LREQ);
return (@REQDPKGS);
}
sub fetchrpm {
my ( $self, $file, $md5sum ) = @_;
my ($realfile) = $file;
my $now = time();
my $mday = $self->{"mday"};
my $mon = $self->{"mon"};
my $year = $self->{"year"};
chdir(".");
my ($cwd) = $ENV{'PWD'};
chomp($cwd);
$realfile =~ s/^\/?linux\/distros\/redhat\///g;
$realfile =~ s/^\/?redhat\/linux\///g;
$realfile =~ s/^\/?redhat\///g;
my @BS = split( /\//, $realfile );
my $basefile = $BS[$#BS];
my $legacy = '';
if ( $realfile =~ /7\.3\//
|| $realfile =~ /9\.0\//
|| $realfile =~ /\/9\// ) {
$legacy = '.legacy';
$realfile =~ s/\/?en\//\//g;
$realfile =~ s/^\///g;
if ( $realfile =~ /updates\// ) {
#swap source and version
my @RF = split( /\//, $realfile );
my $p0 = $RF[1];
my $p1 = $RF[0];
$RF[0] = $p0;
$RF[1] = $p1;
$realfile = join( "/", @RF );
$realfile =~ s/\/?os\//\//g;
}
elsif ( $realfile =~ /RedHat\/RPMS/ ) {
$realfile =~ s/\/?RedHat\/RPMS\//\//g;
}
}
if ( !-e "/root/.cpupdates/$mon-$mday-$year.mirrors.times" ) {
print "Fetching rpm mirror timestamp...";
cPanelRPM::httpreq( 'updates.cpanel.net', "/pub/rpminstall/redhat/mirrors${legacy}.times", "/root/.cpupdates/$mon-$mday-$year.mirrors.times" );
print "Done\n";
if ( !-e "/root/.cpupdates/$mon-$mday-$year.mirrors.times" ) {
die "Cannot fetch mirror list";
}
}
open( MT, "/root/.cpupdates/$mon-$mday-$year.mirrors.times" );
my $mirrortime = <MT>;
close(MT);
chomp($mirrortime);
if ( ( $mirrortime - 500 ) > ( stat("/root/.cpupdates/mirrors.lst") )[9] || !-e "/root/.cpupdates/mirrors.lst" ) {
print "Fetching rpm mirror list...";
if ( -e "/bin/bzip2" || -e "/usr/bin/bzip2" ) {
cPanelRPM::httpreq( 'updates.cpanel.net', "/pub/rpminstall/redhat/mirrors${legacy}.lst.bz2", "/root/.cpupdates/mirrors.lst.bz2" );
system( "bzip2", "-d", "-f", "/root/.cpupdates/mirrors.lst.bz2" );
}
else {
cPanelRPM::httpreq( 'updates.cpanel.net', "/pub/rpminstall/redhat/mirrors${legacy}.lst.gz", "/root/.cpupdates/mirrors.lst.gz" );
system( "gzip", "-d", "-f", "/root/.cpupdates/mirrors.lst.gz" );
}
print "Done\n";
if ( !-e "/root/.cpupdates/mirrors.lst" ) {
die "Cannot fetch mirror list";
}
}
open( MIRRORS, "/root/.cpupdates/mirrors.lst" );
my @MIRRORS = <MIRRORS>;
close(MIRRORS);
print "Testing connection speed...(this could take a while)...";
system("/scripts/pingtest");
print ".Done\n";
my (%PINGTIMES);
opendir( PT, "/root/.cpupdates/pingtimes" );
my @PT = readdir(PT);
closedir(PT);
foreach my $pt (@PT) {
next if ( $pt =~ /^\./ );
open( PINGTIMES, "/root/.cpupdates/pingtimes/${pt}" );
$PINGTIMES{ ${pt} } = <PINGTIMES>;
chomp $PINGTIMES{ ${pt} };
close(PINGTIMES);
}
undef @PT;
my (%URLS);
$URLS{'updates.cpanel.net'} = "http://updates.cpanel.net/";
foreach my $mirror ( sort { rand($a) <=> rand($b) } @MIRRORS ) {
chomp($mirror);
$mirror =~ /([^\:]+):\/\/([^\/]+)(\S+)/;
my $pro = $1;
my $host = $2;
my $url = $3;
next if ( $mirror =~ /^[\s\r\n\t]*$/ );
$URLS{$host} = $mirror;
}
if ( !-e "/var/spool/cpupdates" ) {
mkdir( "/var/spool/cpupdates", 0700 );
}
chdir("/var/spool/cpupdates");
my (%MIRRORSPEED);
my (%MIRRORTIME);
open( MIRRORSPEEDS, "/root/.cpupdates/mirrors.speeds" );
while (<MIRRORSPEEDS>) {
chomp();
my ( $mirror, $speed, $mirrortime ) = split( /=/, $_ );
if ( $mirrortime + ( 86400 * 15 ) > ${now} ) { next(); }
$MIRRORSPEED{$mirror} = $speed;
$MIRRORTIME{$mirror} = $mirrortime;
}
close(MIRRORSPEEDS);
my $dc = 0;
foreach my $host ( sort { $PINGTIMES{$a} <=> $PINGTIMES{$b} } keys %PINGTIMES ) {
if ( $dc >= 4 ) { print "Four usable mirrors located\n"; last; }
if ( $MIRRORSPEED{$host} eq "" ) {
print "Ping:$PINGTIMES{$host} ";
$MIRRORSPEED{$host} = testmirrorspeed( $realfile, $host, $URLS{$host}, $legacy );
}
if ( $MIRRORSPEED{$host} > 1 ) { $dc++; }
}
open( MIRRORSPEEDS, ">/root/.cpupdates/mirrors.speeds" );
foreach my $mirror ( keys %MIRRORSPEED ) {
print MIRRORSPEEDS "${mirror}=$MIRRORSPEED{$mirror}=$MIRRORTIME{$mirror}\n";
}
close(MIRRORSPEEDS);
$dc = 0;
foreach my $host ( sort { $MIRRORSPEED{$b} <=> $MIRRORSPEED{$a} } keys %MIRRORSPEED ) {
$dc++;
if ( $dc >= 10 ) { last; }
last if ( ( stat("$basefile") )[7] > 1 && getmd5sum($basefile) eq $md5sum );
unlink("/var/spool/cpupdates/$basefile");
if ( -e "/usr/bin/wget" || -e "/usr/local/bin/wget" ) {
print "Trying to fetch ${basefile} from $URLS{$host} using wget...\n";
system( "wget", "-t", "2", "--timeout", "300", "--passive-ftp", "-O", "${basefile}", $URLS{$host} . "/" . ${realfile} );
}
elsif ( -e "/usr/bin/curl" || -e "/usr/local/bin/curl" ) {
print "Trying to fetch ${basefile} from $URLS{$host} using curl...\n";
system( "curl", "-m", "1000", "-o", "${basefile}", $URLS{$host} . "/" . ${realfile} );
}
elsif ( $URLS{$host} =~ /^ftp/ && ( -e "/usr/bin/ncftpget" || -e "/usr/local/bin/ncftpget" ) ) {
print "Trying to fetch ${basefile} from $URLS{$host} using ncftpget...\n";
system( "ncftpget", "-z", "${basefile}", $URLS{$host} . "/" . ${realfile} );
}
else {
die "wget/curl/ncftpget is not installed";
}
}
delete @MIRRORSPEED{ keys %MIRRORSPEED };
delete @MIRRORTIME{ keys %MIRRORTIME };
if ( $md5sum eq getmd5sum($basefile) ) {
chdir($cwd);
return (1);
}
chdir($cwd);
return (0);
}
sub pinghost {
my ($host) = @_;
my ($pingtime);
open( PING, "-|" ) || exec( "ping", "-w", "3", "-c", "2", $host );
while (<PING>) {
if (/[\d\.]+\/([\d\.]+)/) {
$pingtime = $1;
}
}
close(PING);
if ( $pingtime eq "" ) { $pingtime = 1000; }
return ($pingtime);
}
sub getmd5sum {
my ($file) = @_;
my ($md5);
open( MD5, "-|" ) || exec 'md5sum', $file;
while (<MD5>) {
chomp();
( $md5, undef ) = split( /\s+/, $_ );
last();
}
close(MD5);
return ($md5);
}
sub testmirrorspeed {
my ( $base, $host, $url, $legacy ) = @_;
$base =~ /([\d\.]+)\//;
my $version = $1;
$base = "${version}/en/os/i386";
my $speed;
open( WNULL, ">/dev/null" );
open( RNULL, "</dev/null" );
my $file = 'RELEASE-NOTES';
if ( $legacy ne "" ) {
$base = '';
$url =~ s/\/?redhat\/?//g;
$file = 'index.html';
}
if ( $url =~ /^http/ ) {
print "Testing connection speed to $host using pureperl...";
my $RES = Cpanel::HttpTimer::timedrequest( url => $url . "/" . ${base} . "/" . $file );
$speed = $$RES{'speed'};
}
else {
unlink($file);
my $tpid;
if ( -e "/usr/bin/wget" || -e "/usr/local/bin/wget" ) {
print "Testing connection speed to $host using wget...";
$tpid = open3( "<&RNULL", ">&WNULL", \*ERRFH, "wget", "--timeout", "90", "-t", "2", "--passive-ftp", "-O", $file, $url . "/" . ${base} . "/" . $file );
while (<ERRFH>) {
if (/\(([\d\.]+)\s+([^\)]+)/) {
$speed = $1;
if ( $2 =~ /^k/i ) { $speed = ( $speed * 1000 ); }
if ( $2 =~ /^m/i ) { $speed = ( $speed * 1000000 ); }
if ( $2 =~ /^g/i ) { $speed = ( $speed * 1000000000 ); }
}
}
close(ERRFH);
}
elsif ( -e '/usr/bin/curl' || -e '/usr/local/bin/curl' ) {
print "Testing connection speed to $host using curl...";
$tpid = open3( '<&RNULL', '>&WNULL', \*ERRFH, 'curl', '-m', '100', '-o', $file, $url . "/" . ${base} . "/" . $file );
while (<ERRFH>) {
# 7 628k 7 46091 0 0 39876
if (/\s*\d+\s+\S+\s+\d+\S+\s+\d+\s+\S+\s+(\d+)(\S+)/) {
$speed = $1;
if ( $2 =~ /k$/i ) { $speed = ( $speed * 1000 ); }
if ( $2 =~ /m$/i ) { $speed = ( $speed * 1000000 ); }
if ( $2 =~ /g$/i ) { $speed = ( $speed * 1000000000 ); }
}
}
close(ERRFH);
}
elsif ( $url =~ /^ftp/ && ( -e "/usr/bin/ncftpget" || -e "/usr/local/bin/ncftpget" ) ) {
print "Testing connection speed to $host using ncftpget...";
open( ERRFH, "-|" ) || exec( "ncftpget", "-z", $url . "/" . ${base} . "/" . $file );
while (<ERRFH>) {
if (/([\d\.]+)\s+(\S+)\s*$/) {
$speed = $1;
if ( $2 =~ /^k/i ) { $speed = ( $speed * 1000 ); }
if ( $2 =~ /^m/i ) { $speed = ( $speed * 1000000 ); }
if ( $2 =~ /^g/i ) { $speed = ( $speed * 1000000000 ); }
}
}
close(ERRFH);
}
unlink($file);
close(RNULL);
close(WNULL);
waitpid( $tpid, 0 );
}
if ( $speed eq "" ) {
$speed = 0;
print "test failed...Done\n";
}
else {
print "($speed bytes/s)...Done\n";
}
return ($speed);
}
1;