@ -268,7 +268,7 @@ use constant {
ERROR => 5,
};
my $versionNum = '1.3 ';
my $versionNum = '1.4-rc1 ';
# Some global variables
# Remember kids, global variables are evil! I only get to do this
@ -1016,10 +1016,13 @@ sub get_fullpath
# First parameter: Hostname of the server (i.e. kdesvn-build.kde.org)
# Second parameter: Path of the file on the host (i.e. /files/blah.tbz2)
# Third parameter: Filename to save as (i.e. $ENV{HOME}/blah.tbz2)
# Fourth parameter: Reference to hash used to record if a redirection occurred,
# and how many redirections have already been attempted.
# See download_file()
# Return value is 0 for failure, non-zero for success.
sub download_http_file
{
my ($host, $path, $filename) = @_;
my ($host, $path, $filename, $info ) = @_;
return 0 unless has_Net_HTTP();
my $conn = Net::HTTP->new (Host => $host);
@ -1040,6 +1043,25 @@ sub download_http_file
my ($code, $msg, %h) = $conn->read_response_headers();
# Try to handle redirections. We handle them all pretty much the same,
# i.e. if the Location response is present use that, otherwise error out.
while (int $code / 100 == 3)
{
$info->{'redir_count'}++;
$conn->close(); # Error or not, we're done with this connection.
if (not $h{'Location'})
{
error "Unable to download file r[$path], ambiguous redirection.";
return 0;
}
my $destination = $h{'Location'};
$destination =~ s/^Location:\s*//;
$info->{'redirection'} = $destination;
return 0;
}
if (200 != $code)
{
error "Unable to download file r[$path]:\n\tr[b[$msg]";
@ -1120,7 +1142,8 @@ sub download_ftp_file
$ftp->binary(); # Switch to binary mode.
# Check if file exists.
if ($ftp->size($path) <= 0)
my $size = $ftp->size($path);
if (not $size or $size <= 0)
{
$ftp->quit();
return 0;
@ -1156,28 +1179,51 @@ sub download_file
return 1;
}
my ($protocol, $host, $path) = ($url =~ m{^([^:]+)://([^/]+)(/.*)$});
my ($protocol, $host, $path);
my $info = { 'redir_count' => 0, 'redirection' => '' };
if (not defined $url or not defined $host or not defined $path )
while ($info->{'redir_count'} < 5 )
{
error "Trying to download file from invalid URL: r[$url]";
return 0;
}
($protocol, $host, $path) = ($url =~ m{^([^:]+)://([^/]+)(/.*)$});
if (not defined $url or not defined $host or not defined $path)
{
error "Trying to download file from invalid URL: r[$url]";
return 0;
}
# Not sure if https works but no harm in letting it try.
if ($protocol =~ /^https?$/)
{
whisper "Downloading g[$path] from g[$url]";
return download_http_file($host, $path, $filename);
}
elsif ($protocol eq 'ftp')
{
whisper "Downloading g[$path] from g[$url]";
return download_ftp_file($host, $path, $filename);
$info->{'redirection'} = '';
# Not sure if https works but no harm in letting it try.
if ($protocol =~ /^https?$/)
{
whisper "Downloading g[$path] from g[$url]";
my $result = download_http_file($host, $path, $filename, $info);
if (not $result and $info->{'redirection'})
{
# Try again at new URL.
$url = $info->{'redirection'};
whisper "Redirecting to y[$url]";
next;
}
else
{
return $result;
}
}
elsif ($protocol eq 'ftp')
{
whisper "Downloading g[$path] from g[$url]";
return download_ftp_file($host, $path, $filename);
}
else
{
error "Trying to download file ($url), but";
error "\tthe r[$protocol] protocol is unsupported.";
return 0;
}
}
error "Trying to download file ($url), but";
error "\tthe r[$protocol] protocol is unsupported.";
return 0;
}
@ -1206,7 +1252,8 @@ sub install_module_snapshot
if ($branch eq 'trunk')
{
$filename = "$moduleName-svn.tar.bz2";
$url = "ftp://ftp.kde.org/pub/kde/unstable/snapshots/$filename";
#$url = "ftp://ftp.kde.org/pub/kde/unstable/snapshots/$filename";
$url = "http://download.kde.org/download.php?url=unstable/snapshots/$moduleName-svn.tar.bz2";
$dirName = "$moduleName";
if (download_module_snapshot($module, $filename, $url, $dirName))
@ -1301,7 +1348,7 @@ sub download_module_snapshot
error "Unable to extract snapshot for r[$module]: $savedError";
# Remove any created portions of the module tree.
safe_system("rm", "-rf", "$dirName" );
safe_rmtree($dirName );
return 0;
}
@ -1314,8 +1361,8 @@ sub download_module_snapshot
error "Unable to move directory for r[$module] into place: r[$!]";
# Remove any created portions of the module tree.
safe_system("rm", "-rf", $dirName);
safe_system("rm", "-rf", $moduleName);
safe_rmtree( $dirName);
safe_rmtree( $moduleName);
return 0;
}
@ -1330,6 +1377,7 @@ sub download_module_snapshot
my $curSvnHost = `svn info | grep ^URL`;
$curSvnHost =~ s/^URL:\s*//;
$curSvnHost =~ s/\/home\/kde.*$/\/home\/kde/; # Remove stuff after /home/kde
chomp $curSvnHost;
info "\tFinalizing Subversion information for g[$module]";
@ -1347,7 +1395,7 @@ sub download_module_snapshot
# Remove any created portions of the module tree.
p_chdir("..");
safe_system("rm", "-rf", $moduleName);
safe_rmtree( $moduleName);
return 0;
}
@ -1369,7 +1417,7 @@ sub download_module_snapshot
# Remove any created portions of the module tree.
p_chdir("..");
safe_system("rm", "-rf", $moduleName);
safe_rmtree( $moduleName);
return 0;
}
@ -1984,6 +2032,60 @@ sub path_to_prog
return undef;
}
# Subroutine to delete a directory and all files and subdirectories within.
# Does nothing in pretend mode. An analogue to "rm -rf" from Linux.
# Requires File::Find module.
#
# First parameter: Path to delete
# Returns boolean true on success, boolean false for failure.
sub safe_rmtree
{
my $path = shift;
my $delete_file_or_dir = sub {
# $_ is the filename/dirname
return if $_ eq '.' or $_ eq '..';
if (-f $_)
{
unlink ($_) or die "Unable to delete $File::Find::name!";
}
elsif (-d $_)
{
rmdir ($File::Find::name) or die "Unable to remove directory $File::Find::name: $!";
}
};
if (pretending)
{
pretend "Would have recursively removed $path";
return 1;
}
# Error out because we probably have a logic error even though it would
# delete just fine.
if (not -d $path)
{
error "Cannot recursively remove $path, as it is not a directory.";
return 0;
}
eval {
$@ = '';
finddepth( # finddepth does a postorder traversal.
{
wanted => $delete_file_or_dir,
no_chdir => 1, # We'll end up deleting directories, so prevent this.
}, $path);
};
if ($@)
{
error "Unable to remove directory $path: $@";
return 0;
}
return 1;
}
# Subroutine to run the make command with the arguments given by the passed
# list. The first argument of the list given must be the module that we're
# making. The second argument is the "try number", used in creating the log
@ -4392,7 +4494,7 @@ sub clean_build_system
}
# Let users know we're done so they don't wonder why rm -rf is taking so
# long and oh yeah, why'd my HD so active?...
# long and oh yeah, why's my HD so active?...
info "\tOld build system cleaned, starting new build system.";
}
# or create the directory
@ -5169,14 +5271,14 @@ sub handle_install
# Remove srcdir
my $srcdir = get_fullpath($module, 'source');
note "\tRemoving b[r[$module source].";
system ('rm', '-rf', $srcdir);
safe_rmtree( $srcdir);
}
if($remove_setting eq 'builddir' or $remove_setting eq 'all')
{
# Remove builddir
note "\tRemoving b[r[$module build directory].";
system ('rm', '-rf', $builddir);
safe_rmtree( $builddir);
}
}
@ -5531,6 +5633,7 @@ eval
}
eval { plugin_setup_default_modules(\@update_list, \@build_list, \%package_opts); };
$@ = ''; # Clear errors that result when not using Coverity plugin.
@update_list = get_update_list();
@build_list = get_build_list();