summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xgurpmi25
-rw-r--r--urpm.pm209
-rw-r--r--urpm/get_pkgs.pm218
-rwxr-xr-xurpmi5
-rwxr-xr-xurpmq5
5 files changed, 229 insertions, 213 deletions
diff --git a/gurpmi2 b/gurpmi2
index 323c73f7..62a12b17 100755
--- a/gurpmi2
+++ b/gurpmi2
@@ -15,6 +15,7 @@ use gurpmi;
use urpm::install;
use urpm::media;
use urpm::signature;
+use urpm::get_pkgs;
use Gtk2;
#- GUI globals
@@ -210,7 +211,7 @@ sub do_install_2 () {
sub do_install_3 () {
wait_label(N("Package installation..."));
- my ($local_sources, $list) = $urpm->get_source_packages($state->{selected});
+ my ($local_sources, $list) = urpm::get_pkgs::selected2list($urpm, $state->{selected});
$local_sources || $list or $urpm->{fatal}(3, N("unable to get source packages, aborting"));
my %sources = %$local_sources;
my %error_sources;
@@ -240,7 +241,7 @@ sub do_install_3 () {
foreach my $set (@{$state->{transaction} || []}) {
my (@transaction_list, %transaction_sources);
urpm::install::prepare_transaction($urpm, $set, $list, \%sources, \@transaction_list, \%transaction_sources);
- $urpm->download_packages_of_distant_media(
+ urpm::get_pkgs::download_packages_of_distant_media($urpm,
\@transaction_list,
\%transaction_sources,
\%error_sources,
diff --git a/urpm.pm b/urpm.pm
index 01294940..80895262 100644
--- a/urpm.pm
+++ b/urpm.pm
@@ -369,146 +369,6 @@ sub resolve_dependencies {
$need_restart;
}
-#- select sources for selected packages,
-#- according to keys of the packages hash.
-#- returns a list of lists containing the source description for each rpm,
-#- matching the exact number of registered media; ignored media being
-#- associated to a null list.
-sub get_source_packages {
- my ($urpm, $packages, %options) = @_;
- my (%protected_files, %local_sources, %fullname2id);
-
- #- build association hash to retrieve id and examine all list files.
- foreach (keys %$packages) {
- foreach (split /\|/, $_) {
- if ($urpm->{source}{$_}) {
- $protected_files{$local_sources{$_} = $urpm->{source}{$_}} = undef;
- } else {
- $fullname2id{$urpm->{depslist}[$_]->fullname} = $_ . '';
- }
- }
- }
-
- #- examine each medium to search for packages.
- #- now get rpm file name in hdlist to match list file.
- my %file2fullnames;
- foreach my $pkg (@{$urpm->{depslist} || []}) {
- $file2fullnames{$pkg->filename}{$pkg->fullname} = undef;
- }
-
- #- examine the local repository, which is trusted (no gpg or pgp signature check but md5 is now done).
- my $dh = urpm::sys::opendir_safe($urpm, "$urpm->{cachedir}/rpms");
- if ($dh) {
- while (defined(my $filename = readdir $dh)) {
- my $filepath = "$urpm->{cachedir}/rpms/$filename";
- if (-d $filepath) {
- } elsif ($options{clean_all} || ! -s _) {
- unlink $filepath; #- this file should be removed or is already empty.
- } else {
- if (keys(%{$file2fullnames{$filename} || {}}) > 1) {
- $urpm->{error}(N("there are multiple packages with the same rpm filename \"%s\"", $filename));
- } elsif (keys(%{$file2fullnames{$filename} || {}}) == 1) {
- my ($fullname) = keys(%{$file2fullnames{$filename} || {}});
- if (defined(my $id = delete $fullname2id{$fullname})) {
- $local_sources{$id} = $filepath;
- } else {
- $options{clean_other} && ! exists $protected_files{$filepath} and unlink $filepath;
- }
- } else {
- $options{clean_other} && ! exists $protected_files{$filepath} and unlink $filepath;
- }
- }
- }
- closedir $dh;
- }
-
- if ($options{clean_all}) {
- #- clean download directory, do it here even if this is not the best moment.
- urpm::sys::clean_dir("$urpm->{cachedir}/partial");
- }
-
- my ($error, @list_error, @list, %examined);
-
- foreach my $medium (@{$urpm->{media} || []}) {
- my (%sources, %list_examined, $list_warning);
-
- if (urpm::media::is_valid_medium($medium) && !$medium->{ignore}) {
- #- always prefer a list file if available.
- if ($medium->{list}) {
- if (-r urpm::media::statedir_list($urpm, $medium)) {
- foreach (cat_(urpm::media::statedir_list($urpm, $medium))) {
- chomp;
- if (my ($filename) = m!([^/]*\.rpm)$!) {
- if (keys(%{$file2fullnames{$filename} || {}}) > 1) {
- $urpm->{error}(N("there are multiple packages with the same rpm filename \"%s\"", $filename));
- next;
- } elsif (keys(%{$file2fullnames{$filename} || {}}) == 1) {
- my ($fullname) = keys(%{$file2fullnames{$filename} || {}});
- if (defined(my $id = $fullname2id{$fullname})) {
- if (!/\.delta\.rpm$/ || $urpm->is_delta_installable($urpm->{depslist}[$id], $options{root})) {
- $sources{$id} = "$medium->{url}/$filename";
- }
- }
- $list_examined{$fullname} = $examined{$fullname} = undef;
- }
- } else {
- chomp;
- $error = 1;
- $urpm->{error}(N("unable to correctly parse [%s] on value \"%s\"", urpm::media::statedir_list($urpm, $medium), $_));
- last;
- }
- }
- } else {
- # list file exists but isn't readable
- # report error only if no result found, list files are only readable by root
- push @list_error, N("unable to access list file of \"%s\", medium ignored", $medium->{name});
- $< and push @list_error, " " . N("(retry as root?)");
- next;
- }
- }
- if (defined $medium->{url}) {
- foreach ($medium->{start} .. $medium->{end}) {
- my $pkg = $urpm->{depslist}[$_];
- my $fi = $pkg->filename;
- if (keys(%{$file2fullnames{$fi} || {}}) > 1) {
- $urpm->{error}(N("there are multiple packages with the same rpm filename \"%s\"", $fi));
- next;
- } elsif (keys(%{$file2fullnames{$fi} || {}}) == 1) {
- my ($fullname) = keys(%{$file2fullnames{$fi} || {}});
- unless (exists($list_examined{$fullname})) {
- ++$list_warning;
- if (defined(my $id = $fullname2id{$fullname})) {
- if ($fi !~ /\.delta\.rpm$/ || $urpm->is_delta_installable($urpm->{depslist}[$id], $options{root})) {
- $sources{$id} = "$medium->{url}/" . $fi;
- }
- }
- $examined{$fullname} = undef;
- }
- }
- }
- $list_warning && $medium->{list} && -r urpm::media::statedir_list($urpm, $medium) && -f _
- and $urpm->{error}(N("medium \"%s\" uses an invalid list file:
- mirror is probably not up-to-date, trying to use alternate method", $medium->{name}));
- } elsif (!%list_examined) {
- $error = 1;
- $urpm->{error}(N("medium \"%s\" does not define any location for rpm files", $medium->{name}));
- }
- }
- push @list, \%sources;
- }
-
- #- examine package list to see if a package has not been found.
- foreach (grep { ! exists($examined{$_}) } keys %fullname2id) {
- # print list errors only once if any
- $urpm->{error}($_) foreach @list_error;
- @list_error = ();
- $error = 1;
- $urpm->{error}(N("package %s is not found.", $_));
- }
-
- $error ? @{[]} : (\%local_sources, \@list);
-}
-
#- checks whether the delta RPM represented by $pkg is installable wrt the
#- RPM DB on $root. For this, it extracts the rpm version to which the
#- delta applies from the delta rpm filename itself. So naming conventions
@@ -534,9 +394,10 @@ sub download_source_packages {
my %sources = %$local_sources;
my %error_sources;
+ require urpm::get_pkgs;
urpm::sys::lock_urpmi_db($urpm, 'exclusive') if !$options{nolock};
urpm::removable::copy_packages_of_removable_media($urpm, $list, \%sources, $options{ask_for_medium}) or return;
- $urpm->download_packages_of_distant_media($list, \%sources, \%error_sources, %options);
+ urpm::get_pkgs::download_packages_of_distant_media($urpm, $list, \%sources, \%error_sources, %options);
urpm::sys::unlock_urpmi_db($urpm) unless $options{nolock};
%sources, %error_sources;
@@ -548,72 +409,6 @@ sub exlock_urpmi_db {
urpm::sys::lock_urpmi_db($urpm, 'exclusive');
}
-# TODO verify that files are downloaded from the right corresponding media
-#- options: quiet, callback,
-sub download_packages_of_distant_media {
- my ($urpm, $list, $sources, $error_sources, %options) = @_;
-
- #- get back all ftp and http accessible rpm files into the local cache
- foreach my $n (0..$#$list) {
- my %distant_sources;
-
- #- ignore media that contain nothing for the current set of files
- values %{$list->[$n]} or next;
-
- #- examine all files to know what can be indexed on multiple media.
- while (my ($i, $url) = each %{$list->[$n]}) {
- #- the given URL is trusted, so the file can safely be ignored.
- defined $sources->{$i} and next;
- my $local_file = file_from_local_url($url);
- if ($local_file && $local_file =~ /\.rpm$/) {
- if (-r $local_file) {
- $sources->{$i} = $local_file;
- } else {
- $error_sources->{$i} = $local_file;
- }
- } elsif ($url =~ m!^([^:]*):/(.*/([^/]*\.rpm))\Z!) {
- $distant_sources{$i} = "$1:/$2"; #- will download now
- } else {
- $urpm->{error}(N("malformed URL: [%s]", $url));
- }
- }
-
- #- download files from the current medium.
- if (%distant_sources) {
- $urpm->{log}(N("retrieving rpm files from medium \"%s\"...", $urpm->{media}[$n]{name}));
- if (urpm::download::sync($urpm, $urpm->{media}[$n], [ values %distant_sources ],
- quiet => $options{quiet}, resume => $urpm->{options}{resume}, callback => $options{callback})) {
- $urpm->{log}(N("...retrieving done"));
- } else {
- $urpm->{error}(N("...retrieving failed: %s", $@));
- }
- #- clean files that have not been downloaded, but keep in mind
- #- there have been problems downloading them at least once, this
- #- is necessary to keep track of failing downloads in order to
- #- present the error to the user.
- foreach my $i (keys %distant_sources) {
- my ($filename) = $distant_sources{$i} =~ m|/([^/]*\.rpm)$|;
- if ($filename && -s "$urpm->{cachedir}/partial/$filename" &&
- URPM::verify_rpm("$urpm->{cachedir}/partial/$filename", nosignatures => 1))
- {
- #- it seems the the file has been downloaded correctly and has been checked to be valid.
- unlink "$urpm->{cachedir}/rpms/$filename";
- urpm::util::move("$urpm->{cachedir}/partial/$filename", "$urpm->{cachedir}/rpms/$filename");
- -r "$urpm->{cachedir}/rpms/$filename" and $sources->{$i} = "$urpm->{cachedir}/rpms/$filename";
- }
- unless ($sources->{$i}) {
- $error_sources->{$i} = $distant_sources{$i};
- }
- }
- }
- }
-
- #- clean failed download which have succeeded.
- delete @$error_sources{keys %$sources};
-
- 1;
-}
-
#- extract package that should be installed instead of upgraded,
#- sources is a hash of id -> source rpm filename.
sub extract_packages_to_install {
diff --git a/urpm/get_pkgs.pm b/urpm/get_pkgs.pm
new file mode 100644
index 00000000..29a3ce1f
--- /dev/null
+++ b/urpm/get_pkgs.pm
@@ -0,0 +1,218 @@
+package urpm::get_pkgs;
+
+# $Id$
+
+use urpm::msg;
+use urpm::sys;
+use urpm::util;
+use urpm::media;
+use urpm 'file_from_local_url';
+
+
+#- select sources for selected packages,
+#- according to keys of the packages hash.
+#- returns a list of lists containing the source description for each rpm,
+#- matching the exact number of registered media; ignored media being
+#- associated to a null list.
+sub selected2list {
+ my ($urpm, $packages, %options) = @_;
+ my (%protected_files, %local_sources, %fullname2id);
+
+ #- build association hash to retrieve id and examine all list files.
+ foreach (keys %$packages) {
+ foreach (split /\|/, $_) {
+ if ($urpm->{source}{$_}) {
+ $protected_files{$local_sources{$_} = $urpm->{source}{$_}} = undef;
+ } else {
+ $fullname2id{$urpm->{depslist}[$_]->fullname} = $_ . '';
+ }
+ }
+ }
+
+ #- examine each medium to search for packages.
+ #- now get rpm file name in hdlist to match list file.
+ my %file2fullnames;
+ foreach my $pkg (@{$urpm->{depslist} || []}) {
+ $file2fullnames{$pkg->filename}{$pkg->fullname} = undef;
+ }
+
+ #- examine the local repository, which is trusted (no gpg or pgp signature check but md5 is now done).
+ my $dh = urpm::sys::opendir_safe($urpm, "$urpm->{cachedir}/rpms");
+ if ($dh) {
+ while (defined(my $filename = readdir $dh)) {
+ my $filepath = "$urpm->{cachedir}/rpms/$filename";
+ if (-d $filepath) {
+ } elsif ($options{clean_all} || ! -s _) {
+ unlink $filepath; #- this file should be removed or is already empty.
+ } else {
+ if (keys(%{$file2fullnames{$filename} || {}}) > 1) {
+ $urpm->{error}(N("there are multiple packages with the same rpm filename \"%s\"", $filename));
+ } elsif (keys(%{$file2fullnames{$filename} || {}}) == 1) {
+ my ($fullname) = keys(%{$file2fullnames{$filename} || {}});
+ if (defined(my $id = delete $fullname2id{$fullname})) {
+ $local_sources{$id} = $filepath;
+ } else {
+ $options{clean_other} && ! exists $protected_files{$filepath} and unlink $filepath;
+ }
+ } else {
+ $options{clean_other} && ! exists $protected_files{$filepath} and unlink $filepath;
+ }
+ }
+ }
+ closedir $dh;
+ }
+
+ if ($options{clean_all}) {
+ #- clean download directory, do it here even if this is not the best moment.
+ urpm::sys::clean_dir("$urpm->{cachedir}/partial");
+ }
+
+ my ($error, @list_error, @list, %examined);
+
+ foreach my $medium (@{$urpm->{media} || []}) {
+ my (%sources, %list_examined, $list_warning);
+
+ if (urpm::media::is_valid_medium($medium) && !$medium->{ignore}) {
+ #- always prefer a list file if available.
+ if ($medium->{list}) {
+ if (-r urpm::media::statedir_list($urpm, $medium)) {
+ foreach (cat_(urpm::media::statedir_list($urpm, $medium))) {
+ chomp;
+ if (my ($filename) = m!([^/]*\.rpm)$!) {
+ if (keys(%{$file2fullnames{$filename} || {}}) > 1) {
+ $urpm->{error}(N("there are multiple packages with the same rpm filename \"%s\"", $filename));
+ next;
+ } elsif (keys(%{$file2fullnames{$filename} || {}}) == 1) {
+ my ($fullname) = keys(%{$file2fullnames{$filename} || {}});
+ if (defined(my $id = $fullname2id{$fullname})) {
+ if (!/\.delta\.rpm$/ || $urpm->is_delta_installable($urpm->{depslist}[$id], $options{root})) {
+ $sources{$id} = "$medium->{url}/$filename";
+ }
+ }
+ $list_examined{$fullname} = $examined{$fullname} = undef;
+ }
+ } else {
+ chomp;
+ $error = 1;
+ $urpm->{error}(N("unable to correctly parse [%s] on value \"%s\"", urpm::media::statedir_list($urpm, $medium), $_));
+ last;
+ }
+ }
+ } else {
+ # list file exists but isn't readable
+ # report error only if no result found, list files are only readable by root
+ push @list_error, N("unable to access list file of \"%s\", medium ignored", $medium->{name});
+ $< and push @list_error, " " . N("(retry as root?)");
+ next;
+ }
+ }
+ if (defined $medium->{url}) {
+ foreach ($medium->{start} .. $medium->{end}) {
+ my $pkg = $urpm->{depslist}[$_];
+ my $fi = $pkg->filename;
+ if (keys(%{$file2fullnames{$fi} || {}}) > 1) {
+ $urpm->{error}(N("there are multiple packages with the same rpm filename \"%s\"", $fi));
+ next;
+ } elsif (keys(%{$file2fullnames{$fi} || {}}) == 1) {
+ my ($fullname) = keys(%{$file2fullnames{$fi} || {}});
+ unless (exists($list_examined{$fullname})) {
+ ++$list_warning;
+ if (defined(my $id = $fullname2id{$fullname})) {
+ if ($fi !~ /\.delta\.rpm$/ || $urpm->is_delta_installable($urpm->{depslist}[$id], $options{root})) {
+ $sources{$id} = "$medium->{url}/" . $fi;
+ }
+ }
+ $examined{$fullname} = undef;
+ }
+ }
+ }
+ $list_warning && $medium->{list} && -r urpm::media::statedir_list($urpm, $medium) && -f _
+ and $urpm->{error}(N("medium \"%s\" uses an invalid list file:
+ mirror is probably not up-to-date, trying to use alternate method", $medium->{name}));
+ } elsif (!%list_examined) {
+ $error = 1;
+ $urpm->{error}(N("medium \"%s\" does not define any location for rpm files", $medium->{name}));
+ }
+ }
+ push @list, \%sources;
+ }
+
+ #- examine package list to see if a package has not been found.
+ foreach (grep { ! exists($examined{$_}) } keys %fullname2id) {
+ # print list errors only once if any
+ $urpm->{error}($_) foreach @list_error;
+ @list_error = ();
+ $error = 1;
+ $urpm->{error}(N("package %s is not found.", $_));
+ }
+
+ $error ? @{[]} : (\%local_sources, \@list);
+}
+
+# TODO verify that files are downloaded from the right corresponding media
+#- options: quiet, callback,
+sub download_packages_of_distant_media {
+ my ($urpm, $list, $sources, $error_sources, %options) = @_;
+
+ #- get back all ftp and http accessible rpm files into the local cache
+ foreach my $n (0..$#$list) {
+ my %distant_sources;
+
+ #- ignore media that contain nothing for the current set of files
+ values %{$list->[$n]} or next;
+
+ #- examine all files to know what can be indexed on multiple media.
+ while (my ($i, $url) = each %{$list->[$n]}) {
+ #- the given URL is trusted, so the file can safely be ignored.
+ defined $sources->{$i} and next;
+ my $local_file = file_from_local_url($url);
+ if ($local_file && $local_file =~ /\.rpm$/) {
+ if (-r $local_file) {
+ $sources->{$i} = $local_file;
+ } else {
+ $error_sources->{$i} = $local_file;
+ }
+ } elsif ($url =~ m!^([^:]*):/(.*/([^/]*\.rpm))\Z!) {
+ $distant_sources{$i} = "$1:/$2"; #- will download now
+ } else {
+ $urpm->{error}(N("malformed URL: [%s]", $url));
+ }
+ }
+
+ #- download files from the current medium.
+ if (%distant_sources) {
+ $urpm->{log}(N("retrieving rpm files from medium \"%s\"...", $urpm->{media}[$n]{name}));
+ if (urpm::download::sync($urpm, $urpm->{media}[$n], [ values %distant_sources ],
+ quiet => $options{quiet}, resume => $urpm->{options}{resume}, callback => $options{callback})) {
+ $urpm->{log}(N("...retrieving done"));
+ } else {
+ $urpm->{error}(N("...retrieving failed: %s", $@));
+ }
+ #- clean files that have not been downloaded, but keep in mind
+ #- there have been problems downloading them at least once, this
+ #- is necessary to keep track of failing downloads in order to
+ #- present the error to the user.
+ foreach my $i (keys %distant_sources) {
+ my ($filename) = $distant_sources{$i} =~ m|/([^/]*\.rpm)$|;
+ if ($filename && -s "$urpm->{cachedir}/partial/$filename" &&
+ URPM::verify_rpm("$urpm->{cachedir}/partial/$filename", nosignatures => 1))
+ {
+ #- it seems the the file has been downloaded correctly and has been checked to be valid.
+ unlink "$urpm->{cachedir}/rpms/$filename";
+ urpm::util::move("$urpm->{cachedir}/partial/$filename", "$urpm->{cachedir}/rpms/$filename");
+ -r "$urpm->{cachedir}/rpms/$filename" and $sources->{$i} = "$urpm->{cachedir}/rpms/$filename";
+ }
+ unless ($sources->{$i}) {
+ $error_sources->{$i} = $distant_sources{$i};
+ }
+ }
+ }
+ }
+
+ #- clean failed download which have succeeded.
+ delete @$error_sources{keys %$sources};
+
+ 1;
+}
+
+1;
diff --git a/urpmi b/urpmi
index c0120b07..ea749a52 100755
--- a/urpmi
+++ b/urpmi
@@ -25,6 +25,7 @@ use urpm::args;
use urpm::msg;
use urpm::install;
use urpm::media;
+use urpm::get_pkgs;
use urpm::signature;
use urpm::util qw(untaint difference2 member);
@@ -581,7 +582,7 @@ if (@root_only) {
message_input("$msg:\n$p\n$msg2" . N(" (Y/n) "), $force && $yesexpr, boolean => 1) =~ /[$noexpr]/ and exit 0;
}
-my ($local_sources, $list) = $urpm->get_source_packages(
+my ($local_sources, $list) = urpm::get_pkgs::selected2list($urpm,
$state->{selected},
clean_all => $clean,
clean_other => !$noclean && $urpm->{options}{'pre-clean'},
@@ -629,7 +630,7 @@ foreach my $set (@{$state->{transaction} || []}) {
urpm::install::prepare_transaction($urpm, $set, $list, \%sources, \@transaction_list, \%transaction_sources);
#- first, filter out what is really needed to download for this small transaction.
- $urpm->download_packages_of_distant_media(
+ urpm::get_pkgs::download_packages_of_distant_media($urpm,
\@transaction_list,
\%transaction_sources,
\%error_sources,
diff --git a/urpmq b/urpmq
index d63ab0e1..0924d9ab 100755
--- a/urpmq
+++ b/urpmq
@@ -28,6 +28,7 @@ use urpm::args;
use urpm::msg;
use urpm::sys;
use urpm::media;
+use urpm::get_pkgs;
#- default options.
$urpm::args::options = { use_provides => 1 };
@@ -311,7 +312,7 @@ if ($urpm::args::options{list_aliases}) {
|| $urpm::args::options{list_files}
|| $urpm::args::options{changelog})
{
- my ($local_sources, $list) = $urpm->get_source_packages($state->{selected});
+ my ($local_sources, $list) = urpm::get_pkgs::selected2list($urpm, $state->{selected});
if ($urpm::args::options{info} || $urpm::args::options{list_files} || $urpm::args::options{changelog}
|| $urpm::args::options{summary}) {
@@ -343,7 +344,7 @@ if ($urpm::args::options{list_aliases}) {
};
$packer->extract($tmp_header_dir, @headers);
} elsif (!%downloads) {
- $urpm->download_packages_of_distant_media($list, \%downloads, my $error = {});
+ urpm::get_pkgs::download_packages_of_distant_media($urpm, $list, \%downloads, my $error = {});
warn "missing file $_\n" foreach values %$error;
}
}