File: //proc/self/root/scripts.20110531.215904.25158/cPanelBSDPKGS.pm
package cPanelBSDPKGS;
# cpanel - cPanelBSDPKGS.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 Cpanel::OSSys;
use Socket;
use Cpanel::HttpTimer;
use strict;
use Cwd 'chdir';
use IPC::Open3;
my ( $system, $release, $machine ) = ( Cpanel::OSSys::uname() )[ 0, 2, 4 ];
my $hassigint = 0;
$SIG{'INT'} = sub {
$hassigint = 1;
print "SIGINT received. Cleaning up and halting operations.\n\n";
};
sub checkedbsdpkgs {
if ( !-e "/root/.cpbsdpkgs" ) {
mkdir( "/root/.cpbsdpkgs", 0700 );
}
if ( ( ( stat("/root/.cpbsdpkgs/modulecheck") )[9] + 86400 ) < time() ) {
open( MC, ">/root/.cpbsdpkgs/modulecheck" );
close(MC);
return (0);
}
else {
return (1);
}
}
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"; return (); }
}
if ( $inheader && ( /^\n$/ || /^\r\n$/ || /^$/ ) ) { $inheader = 0; }
}
alarm(0);
};
if ( $outfile ne "" ) {
open(HTTPREQF);
return ();
}
return ($page);
}
sub getmirrorlist {
my $now = time();
my (@GOODURLS);
my (%URLS);
my $release = ( Cpanel::OSSys::uname() )[2];
( $release, undef ) = split( /-/, $release );
my $majorrelease = ( split( /\./, $release ) )[0];
my $pkgdir = "packages-${release}-release";
# my $fallbackpkgdir = "packages-${majorrelease}-stable";
my $fallbackpkgdir = $pkgdir; #don't fallback by default
if ( !-e "/root/.cpbsdpkgs" ) {
mkdir( "/root/.cpbsdpkgs", 0700 );
}
if ( !-e "/root/.cpbsdpkgs/mirrors.lst" || ( ( ( stat("/root/.cpbsdpkgs/mirrors.lst") )[9] + ( 86400 * 15 ) ) < ${now} ) ) {
print "Fetching BSD mirrors...";
httpreq( 'httpupdate.cpanel.net', "/pub/bsdmirror/mirrors.lst", "/root/.cpbsdpkgs/mirrors.lst" );
if ( !-e "/root/.cpbsdpkgs/mirrors.lst" ) {
die "Cannot fetch mirror list";
}
print "Done\n";
}
open( MIRRORS, "/root/.cpbsdpkgs/mirrors.lst" );
while (<MIRRORS>) {
chomp();
my $mirror = $_;
my $host = "${mirror}.freebsd.org";
$mirror = "ftp://${host}";
$URLS{$host} = $mirror;
}
close(MIRRORS);
system("/scripts/bsdpkgpingtest");
my (%PINGTIMES);
opendir( PT, "/root/.cpbsdpkgs/pingtimes" );
my @PT = readdir(PT);
closedir(PT);
foreach my $pt (@PT) {
next if ( $pt =~ /^\./ );
open( PINGTIMES, "/root/.cpbsdpkgs/pingtimes/${pt}" );
$PINGTIMES{ ${pt} } = <PINGTIMES>;
chomp $PINGTIMES{ ${pt} };
close(PINGTIMES);
}
undef @PT;
if ( !-e "/var/spool/cpbsdpkgs" ) {
mkdir( "/var/spool/cpbsdpkgs", 0700 );
}
chdir(".");
my ($cwd) = $ENV{'PWD'};
chdir("/var/spool/cpbsdpkgs");
my (%MIRRORSPEED);
open( MIRRORSPEEDS, "/root/.cpbsdpkgs/mirrors.speeds" );
while (<MIRRORSPEEDS>) {
chomp();
my ( $mirror, $speed ) = split( /=/, $_ );
$MIRRORSPEED{$mirror} = $speed;
}
close(MIRRORSPEEDS);
my $dc = 0;
foreach my $host ( sort { $PINGTIMES{$a} <=> $PINGTIMES{$b} } keys %PINGTIMES ) {
if ( $dc >= 3 ) {
#print "Four usable mirrors located\n";
last;
}
if ( $MIRRORSPEED{$host} eq "" ) {
print "Ping:$PINGTIMES{$host} ";
( $MIRRORSPEED{$host} ) = testmirrorspeed( $host, $URLS{$host}, $pkgdir, $fallbackpkgdir );
}
if ( $MIRRORSPEED{$host} > 1 ) { $dc++; }
}
open( MIRRORSPEEDS, ">/root/.cpbsdpkgs/mirrors.speeds" );
foreach my $mirror ( keys %MIRRORSPEED ) {
print MIRRORSPEEDS "${mirror}=$MIRRORSPEED{$mirror}\n";
}
close(MIRRORSPEEDS);
$dc = 0;
foreach my $host ( sort { $MIRRORSPEED{$b} <=> $MIRRORSPEED{$a} } keys %MIRRORSPEED ) {
next if ( $MIRRORSPEED{$host} eq "0" );
push( @GOODURLS, $URLS{$host} );
}
delete @MIRRORSPEED{ keys %MIRRORSPEED };
chdir($cwd);
return (@GOODURLS);
}
sub testmirrorspeed {
my ( $host, $url, $pkgdir, $fallbackpkgdir ) = @_;
my $now = time();
my $speed;
my ( $bsdver, $ver );
( undef, $ver, undef ) = split( /-/, $pkgdir );
( $bsdver, undef ) = split( /\./, $ver );
#$pkgdir = "packages-${bsdver}-stable";
#when using stable only
print "Using package directory: ${pkgdir}, fallback package directory: ${fallbackpkgdir}\n";
unlink("INDEX");
my $tpid;
foreach my $pdir ( $pkgdir, $fallbackpkgdir ) {
if ( $url =~ /^http/ ) {
print "Testing connection speed to $host using pureperl...";
my $RES = Cpanel::HttpTimer::timedrequest( url => $url . "/pub/FreeBSD/ports/${machine}/${pdir}/INDEX" );
$speed = $$RES{'speed'};
}
else {
open( WNULL, ">/dev/null" );
open( RNULL, "</dev/null" );
if ( -e "/usr/bin/fetch" || -e "/usr/local/bin/fetch" ) {
print "Testing connection speed to $host using fetch...";
$tpid = open3( "<&RNULL", ">&WNULL", \*ERRFH, "fetch", "-p", "-T", "500", "-o", "INDEX", $url . "/pub/FreeBSD/ports/${machine}/${pdir}/INDEX" );
while (<ERRFH>) {
if (/\(([\d\.]+)\s+([^\)]+)/) {
print "..old fetch..";
$speed = $1;
if ( $2 =~ /^k/i ) { $speed = ( $speed * 1000 ); }
if ( $2 =~ /^m/i ) { $speed = ( $speed * 1000000 ); }
if ( $2 =~ /^g/i ) { $speed = ( $speed * 1000000000 ); }
}
if (/([\d\.]+)\s+(\w+)ps/) {
print "..new fetch..";
$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/wget" || -e "/usr/local/bin/wget" ) {
print "Testing connection speed to $host using wget...";
$tpid = open3( "<&RNULL", ">&WNULL", \*ERRFH, "wget", "-t", "2", "--passive-ftp", "--timeout", "500", "-O", "INDEX", $url . "/pub/FreeBSD/ports/${machine}/${pdir}/INDEX" );
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', 'INDEX', $url . "/pub/FreeBSD/ports/${machine}/${pdir}/INDEX" );
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 . "/pub/FreeBSD/ports/${machine}/${pdir}/INDEX" );
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("INDEX");
waitpid( $tpid, 0 );
close(RNULL);
close(WNULL);
}
last if ( $speed ne "" );
}
if ( $speed eq "" ) {
$speed = 0;
print "test failed...Done\n";
}
else {
print "($speed bytes/s)...Done\n";
}
return ($speed);
}
1;