summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--urpm.pm2613
1 files changed, 1293 insertions, 1320 deletions
diff --git a/urpm.pm b/urpm.pm
index 0ad56704..7787cb8c 100644
--- a/urpm.pm
+++ b/urpm.pm
@@ -43,8 +43,6 @@ sub new {
media => undef,
options => {},
- #- sync: first argument is options hashref, others are urls to fetch.
- sync => sub { $self->sync_webfetch(@_) },
fatal => sub { printf STDERR "%s\n", $_[1]; exit($_[0]) },
error => sub { printf STDERR "%s\n", $_[0] },
log => sub { printf "%s\n", $_[0] },
@@ -57,69 +55,79 @@ sub new {
$self;
}
-#- syncing algorithms.
+sub requested_ftp_http_downloader {
+ my ($urpm, $media_name) = @_;
+
+ $urpm->{options}{downloader} || #- cmd-line switch
+ $media_name && do {
+ #- per-media config
+ my $m = name2medium($urpm, $media_name);
+ $m && $m->{downloader};
+ } || $urpm->{global_config}{downloader};
+}
+
+#- $medium can be undef
sub sync_webfetch {
- my $urpm = shift;
- my $options = shift;
+ my ($urpm, $medium, $files, $std_options, %more_options) = @_;
+
+ my %options = (
+ dir => "$urpm->{cachedir}/partial",
+ limit_rate => $std_options->{limit_rate},
+ compress => $std_options->{compress},
+ proxy => get_proxy($medium),
+ quiet => $std_options->{quiet}, #- often overridden in the caller, why??
+ $medium ? (media => $medium->{name}) : (),
+ %more_options,
+ );
+ foreach my $cpt (qw(retry wget-options curl-options rsync-options prozilla-options)) {
+ $options{$cpt} = $urpm->{options}{$cpt} if defined $urpm->{options}{$cpt};
+ }
+
+ _sync_webfetch_raw($urpm, $files, \%options);
+}
+
+#- syncing algorithms.
+sub _sync_webfetch_raw {
+ my ($urpm, $files, $options) = @_;
+
my %files;
#- currently ftp and http protocols are managed by curl or wget,
#- ssh and rsync protocols are managed by rsync *AND* ssh.
- foreach (@_) {
- /^([^:_]*)[^:]*:/ or die N("unknown protocol defined for %s", $_);
- push @{$files{$1}}, $_;
+ foreach (@$files) {
+ my $proto = protocol_from_url($_) or die N("unknown protocol defined for %s", $_);
+ push @{$files{$proto}}, $_;
}
if ($files{removable} || $files{file}) {
- eval {
- sync_file($options, @{$files{removable} || []}, @{$files{file} || []});
- };
+ my @l = map { file_from_local_url($_) } @{$files{removable} || []}, @{$files{file} || []};
+ eval { sync_file($options, @l) };
$urpm->{fatal}(10, $@) if $@;
delete @files{qw(removable file)};
}
- foreach my $cpt (qw(wget-options curl-options rsync-options prozilla-options)) {
- $options->{$cpt} = $urpm->{options}{$cpt} if defined $urpm->{options}{$cpt};
- }
if ($files{ftp} || $files{http} || $files{https}) {
- my @webfetch = qw(curl wget prozilla);
- my %webfetch_executables = (curl => 'curl', wget => 'wget', prozilla => 'proz');
- my @available_webfetch = grep {
- -x "/usr/bin/$webfetch_executables{$_}" || -x "/bin/$webfetch_executables{$_}";
- } @webfetch;
+ my @available = urpm::download::available_ftp_http_downloaders();
+
#- use user default downloader if provided and available
- my $option_downloader = $urpm->{options}{downloader}; #- cmd-line switch
- if (!$option_downloader && $options->{media}) { #- per-media config
- (my $m) = grep { $_->{name} eq $options->{media} } @{$urpm->{media}};
- ref $m && defined $m->{downloader} and $option_downloader = $m->{downloader};
- }
- #- global config
- !$option_downloader && exists $urpm->{global_config}{downloader}
- and $option_downloader = $urpm->{global_config}{downloader};
- my ($preferred) = grep { $_ eq $option_downloader } @available_webfetch;
- #- else first downloader of @webfetch is the default one
- $preferred ||= $available_webfetch[0];
- if ($option_downloader ne $preferred && $option_downloader && !our $webfetch_not_available) {
- $urpm->{log}(N("%s is not available, falling back on %s", $option_downloader, $preferred));
- $webfetch_not_available = 1;
- }
- if ($preferred eq 'curl') {
- sync_curl($options, @{$files{ftp} || []}, @{$files{http} || []}, @{$files{https} || []});
- } elsif ($preferred eq 'wget') {
- sync_wget($options, @{$files{ftp} || []}, @{$files{http} || []}, @{$files{https} || []});
- } elsif ($preferred eq 'prozilla') {
- sync_prozilla($options, @{$files{ftp} || []}, @{$files{http} || []}, @{$files{https} || []});
- } else {
- die N("no webfetch found, supported webfetch are: %s\n", join(", ", @webfetch));
+ my $requested_downloader = requested_ftp_http_downloader($urpm, $options->{media});
+ my ($preferred) = grep { $_ eq $requested_downloader } @available;
+ if (!$preferred) {
+ #- else first downloader of @available is the default one
+ $preferred = $available[0];
+ if ($requested_downloader && !our $webfetch_not_available) {
+ $urpm->{log}(N("%s is not available, falling back on %s", $requested_downloader, $preferred));
+ $webfetch_not_available = 1;
+ }
}
+ my $sync = $urpm::download::{"sync_$preferred"} or die N("no webfetch found, supported webfetch are: %s\n", join(", ", urpm::download::ftp_http_downloaders()));
+ $sync->($options, @{$files{ftp} || []}, @{$files{http} || []}, @{$files{https} || []});
+
delete @files{qw(ftp http https)};
}
if ($files{rsync}) {
- sync_rsync($options, @{$files{rsync} || []});
+ sync_rsync($options, @{$files{rsync}});
delete $files{rsync};
}
if ($files{ssh}) {
- my @ssh_files;
- foreach (@{$files{ssh} || []}) {
- m|^ssh://([^/]*)(.*)| and push @ssh_files, "$1:$2";
- }
+ my @ssh_files = map { m!^ssh://([^/]*)(.*)! ? "$1:$2" : () } @{$files{ssh}};
sync_ssh($options, @ssh_files);
delete $files{ssh};
}
@@ -215,37 +223,46 @@ sub read_config {
#- remember if an hdlist or list file is already used
my %filelists;
- foreach (@{$urpm->{media}}) {
+ foreach my $medium (@{$urpm->{media}}) {
foreach my $filetype (qw(hdlist list)) {
- if ($_->{$filetype}) {
- exists($filelists{$filetype}{$_->{$filetype}})
- and $_->{ignore} = 1,
- $urpm->{error}(
- $filetype eq 'hdlist'
- ? N("medium \"%s\" trying to use an already used hdlist, medium ignored", $_->{name})
- : N("medium \"%s\" trying to use an already used list, medium ignored", $_->{name})
- );
- $filelists{$filetype}{$_->{$filetype}} = undef;
+ $medium->{$filetype} or next;
+
+ if ($filelists{$filetype}{$medium->{$filetype}}) {
+ $medium->{ignore} = 1;
+ $urpm->{error}(
+ $filetype eq 'hdlist'
+ ? N("medium \"%s\" trying to use an already used hdlist, medium ignored", $medium->{name})
+ : N("medium \"%s\" trying to use an already used list, medium ignored", $medium->{name})
+ );
+ } else {
+ $filelists{$filetype}{$medium->{$filetype}} = 1;
}
}
}
#- check the presence of hdlist and list files if necessary.
- unless ($options{nocheck_access}) {
- foreach (@{$urpm->{media}}) {
- $_->{ignore} and next;
- -r "$urpm->{statedir}/$_->{hdlist}" || -r "$urpm->{statedir}/synthesis.$_->{hdlist}" && $_->{synthesis}
- or $_->{ignore} = 1,
- $urpm->{error}(N("unable to access hdlist file of \"%s\", medium ignored", $_->{name}));
- $_->{list} && -r "$urpm->{statedir}/$_->{list}" || defined $_->{url}
- or $_->{ignore} = 1,
- $urpm->{error}(N("unable to access list file of \"%s\", medium ignored", $_->{name}));
+ if (!$options{nocheck_access}) {
+ foreach my $medium (@{$urpm->{media}}) {
+ $medium->{ignore} and next;
+
+ if (-r statedir_hdlist($urpm, $medium)) {}
+ elsif ($medium->{synthesis} && -r statedir_synthesis($urpm, $medium)) {}
+ else {
+ $medium->{ignore} = 1;
+ $urpm->{error}(N("unable to access hdlist file of \"%s\", medium ignored", $medium->{name}));
+ }
+ if ($medium->{list} && -r statedir_list($urpm, $medium)) {}
+ elsif ($medium->{url}) {}
+ else {
+ $medium->{ignore} = 1;
+ $urpm->{error}(N("unable to access list file of \"%s\", medium ignored", $medium->{name}));
+ }
}
}
#- read MD5 sums (usually not in urpmi.cfg but in a separate file)
foreach (@{$urpm->{media}}) {
- if (my $md5sum = get_md5sum("$urpm->{statedir}/MD5SUM", ($_->{synthesis} ? "synthesis." : "") . $_->{hdlist})) {
+ if (my $md5sum = get_md5sum("$urpm->{statedir}/MD5SUM", statedir_hdlist_or_synthesis($urpm, $_))) {
$_->{md5sum} = $md5sum;
}
}
@@ -259,11 +276,9 @@ sub probe_medium {
my ($urpm, $medium, %options) = @_;
local $_;
- foreach (@{$urpm->{media}}) {
- if ($_->{name} eq $medium->{name}) {
- $urpm->{error}(N("trying to override existing medium \"%s\", skipping", $medium->{name}));
- return;
- }
+ if (name2medium($urpm, $medium->{name})) {
+ $urpm->{error}(N("trying to override existing medium \"%s\", skipping", $medium->{name}));
+ return;
}
$medium->{url} ||= $medium->{clear_url};
@@ -283,14 +298,14 @@ sub probe_medium {
} else {
unless ($medium->{ignore} || $medium->{hdlist}) {
$medium->{hdlist} = "hdlist.$medium->{name}.cz";
- -e "$urpm->{statedir}/$medium->{hdlist}" or
+ -e statedir_hdlist($urpm, $medium) or
$medium->{ignore} = 1,
$urpm->{error}(N("unable to find hdlist file for \"%s\", medium ignored", $medium->{name}));
}
unless ($medium->{ignore} || $medium->{list}) {
unless (defined $medium->{url}) {
$medium->{list} = "list.$medium->{name}";
- unless (-e "$urpm->{statedir}/$medium->{list}") {
+ unless (-e statedir_list($urpm, $medium)) {
$medium->{ignore} = 1,
$urpm->{error}(N("unable to find list file for \"%s\", medium ignored", $medium->{name}));
}
@@ -300,8 +315,8 @@ sub probe_medium {
#- there is a little more to do at this point as url is not known, inspect directly list file for it.
unless ($medium->{url}) {
my %probe;
- if (-r "$urpm->{statedir}/$medium->{list}") {
- my $listfile = $urpm->open_safe("<", "$urpm->{statedir}/$medium->{list}");
+ if (-r statedir_list($urpm, $medium)) {
+ my $listfile = $urpm->open_safe("<", statedir_list($urpm, $medium));
if ($listfile) {
while (<$listfile>) {
#- /./ is end of url marker in list file (typically generated by a
@@ -349,45 +364,113 @@ sub is_iso {
$removable_dev && $removable_dev =~ /\.iso$/i;
}
+sub protocol_from_url {
+ my ($url) = @_;
+ $url =~ m!^([^:_]*)[^:]*:! && $1;
+}
+sub file_from_local_url {
+ my ($url) = @_;
+ $url =~ m!^(?:removable[^:]*:/|file:/)?(/.*)! && $1;
+}
+sub file_from_file_url {
+ my ($url) = @_;
+ $url =~ m!^(?:file:/)?(/.*)! && $1;
+}
+
+sub hdlist_or_synthesis_for_virtual_medium {
+ my ($medium) = @_;
+
+ my $path = file_from_file_url($medium->{url}) or return;
+ "$path/$medium->{with_hdlist}";
+}
+
+sub statedir_hdlist_or_synthesis {
+ my ($urpm, $medium) = @_;
+ "$urpm->{statedir}/" . ($medium->{synthesis} ? 'synthesis.' : '') . $medium->{hdlist};
+}
+sub statedir_hdlist {
+ my ($urpm, $medium) = @_;
+ "$urpm->{statedir}/$medium->{hdlist}";
+}
+sub statedir_synthesis {
+ my ($urpm, $medium) = @_;
+ "$urpm->{statedir}/synthesis.$medium->{hdlist}";
+}
+sub statedir_list {
+ my ($urpm, $medium) = @_;
+ "$urpm->{statedir}/$medium->{list}";
+}
+sub cachedir_hdlist {
+ my ($urpm, $medium) = @_;
+ "$urpm->{cachedir}/partial/$medium->{hdlist}";
+}
+sub cachedir_list {
+ my ($urpm, $medium) = @_;
+ "$urpm->{cachedir}/partial/$medium->{list}";
+}
+
+sub name2medium {
+ my ($urpm, $name) = @_;
+ my ($medium) = grep { $_->{name} eq $name } @{$urpm->{media}};
+ $medium;
+}
+
#- probe device associated with a removable device.
sub probe_removable_device {
my ($urpm, $medium) = @_;
- #- try to find device name in url scheme
- if ($medium->{url} && $medium->{url} =~ /^removable_?([^_:]*)(?:_[^:]*)?:/) {
- $medium->{removable} ||= $1 && "/dev/$1";
+ if ($medium->{url} && $medium->{url} =~ /^removable/) {
+ #- try to find device name in url scheme, this is deprecated, use medium option "removable" instead
+ if ($medium->{url} =~ /^removable_?([^_:]*)/) {
+ $medium->{removable} ||= $1 && "/dev/$1";
+ }
} else {
delete $medium->{removable};
+ return;
}
#- try to find device to open/close for removable medium.
- if (exists($medium->{removable})) {
- if (my ($dir) = $medium->{url} =~ m!^(?:(?:file|removable)[^:]*:/)?(/.*)!) {
- my %infos;
- my @mntpoints = urpm::sys::find_mntpoints($dir, \%infos);
- if (@mntpoints > 1) { #- return value is suitable for an hash.
- $urpm->{log}(N("too many mount points for removable medium \"%s\"", $medium->{name}));
- $urpm->{log}(N("taking removable device as \"%s\"", join ',', map { $infos{$_}{device} } @mntpoints));
- }
- if (is_iso($medium->{removable})) {
- $urpm->{log}(N("Medium \"%s\" is an ISO image, will be mounted on-the-fly", $medium->{name}));
- } elsif (@mntpoints) {
- if ($medium->{removable} && $medium->{removable} ne $infos{$mntpoints[-1]}{device}) {
- $urpm->{log}(N("using different removable device [%s] for \"%s\"",
- $infos{$mntpoints[-1]}{device}, $medium->{name}));
- }
- $medium->{removable} = $infos{$mntpoints[-1]}{device};
- } else {
- $urpm->{error}(N("unable to retrieve pathname for removable medium \"%s\"", $medium->{name}));
- }
+ if (my $dir = file_from_local_url($medium->{url})) {
+ my %infos;
+ my @mntpoints = urpm::sys::find_mntpoints($dir, \%infos);
+ if (@mntpoints > 1) { #- return value is suitable for an hash.
+ $urpm->{log}(N("too many mount points for removable medium \"%s\"", $medium->{name}));
+ $urpm->{log}(N("taking removable device as \"%s\"", join ',', map { $infos{$_}{device} } @mntpoints));
+ }
+ if (is_iso($medium->{removable})) {
+ $urpm->{log}(N("Medium \"%s\" is an ISO image, will be mounted on-the-fly", $medium->{name}));
+ } elsif (@mntpoints) {
+ if ($medium->{removable} && $medium->{removable} ne $infos{$mntpoints[-1]}{device}) {
+ $urpm->{log}(N("using different removable device [%s] for \"%s\"",
+ $infos{$mntpoints[-1]}{device}, $medium->{name}));
+ }
+ $medium->{removable} = $infos{$mntpoints[-1]}{device};
} else {
$urpm->{error}(N("unable to retrieve pathname for removable medium \"%s\"", $medium->{name}));
}
+ } else {
+ $urpm->{error}(N("unable to retrieve pathname for removable medium \"%s\"", $medium->{name}));
}
}
+
+sub write_MD5SUM {
+ my ($urpm) = @_;
+
+ #- write MD5SUM file
+ my $fh = $urpm->open_safe('>', "$urpm->{statedir}/MD5SUM") or return 0;
+ foreach my $medium (grep { $_->{md5sum} } @{$urpm->{media}}) {
+ my $s = basename(statedir_hdlist_or_synthesis($urpm, $medium));
+ print $fh "$medium->{md5sum} $s\n";
+ }
+
+ $urpm->{log}(N("wrote %s", "$urpm->{statedir}/MD5SUM"));
+
+ delete $urpm->{md5sum_modified};
+}
+
#- Writes the urpmi.cfg file.
-sub write_config {
+sub write_urpmi_cfg {
my ($urpm) = @_;
#- avoid trashing exiting configuration if it wasn't loaded
@@ -409,20 +492,53 @@ sub write_config {
urpm::cfg::dump_config($urpm->{config}, $config)
or $urpm->{fatal}(6, N("unable to write config file [%s]", $urpm->{config}));
- #- write MD5SUM file
- my $md5sum = $urpm->open_safe('>', "$urpm->{statedir}/MD5SUM") or return 0;
- foreach my $medium (@{$urpm->{media}}) {
- $medium->{md5sum}
- and print $md5sum "$medium->{md5sum} " . ($medium->{synthesis} && "synthesis.") . $medium->{hdlist} . "\n";
- }
- close $md5sum;
-
$urpm->{log}(N("wrote config file [%s]", $urpm->{config}));
#- everything should be synced now.
delete $urpm->{modified};
}
+sub write_config {
+ my ($urpm) = @_;
+
+ write_urpmi_cfg($urpm);
+ write_MD5SUM($urpm);
+}
+
+sub _configure_parallel {
+ my ($urpm, $alias) = @_;
+ my @parallel_options;
+ #- read parallel configuration
+ foreach (cat_("/etc/urpmi/parallel.cfg")) {
+ chomp; s/#.*$//; s/^\s*//; s/\s*$//;
+ /\s*([^:]*):(.*)/ or $urpm->{error}(N("unable to parse \"%s\" in file [%s]", $_, "/etc/urpmi/parallel.cfg")), next;
+ $1 eq $alias and push @parallel_options, $2;
+ }
+ #- if a configuration option has been found, use it; else fatal error.
+ my $parallel_handler;
+ if (@parallel_options) {
+ foreach my $dir (grep { -d $_ } map { "$_/urpm" } @INC) {
+ foreach my $pm (grep { -f $_ } glob("$dir/parallel*.pm")) {
+ #- load parallel modules
+ $urpm->{log}->(N("examining parallel handler in file [%s]", $pm));
+ # perl_checker: require urpm::parallel_ka_run
+ # perl_checker: require urpm::parallel_ssh
+ eval { require $pm; $parallel_handler = $urpm->handle_parallel_options(join("\n", @parallel_options)) };
+ $parallel_handler and last;
+ }
+ $parallel_handler and last;
+ }
+ }
+ if ($parallel_handler) {
+ if ($parallel_handler->{nodes}) {
+ $urpm->{log}->(N("found parallel handler for nodes: %s", join(', ', keys %{$parallel_handler->{nodes}})));
+ }
+ $urpm->{parallel_handler} = $parallel_handler;
+ } else {
+ $urpm->{fatal}(1, N("unable to use parallel option \"%s\"", $alias));
+ }
+}
+
#- read urpmi.cfg file as well as necessary synthesis files
#- options :
#- callback
@@ -448,40 +564,11 @@ sub configure {
$options{parallel} && $options{usedistrib} and $urpm->{fatal}(1, N("Can't use parallel mode with use-distrib mode"));
if ($options{parallel}) {
- my ($parallel_options, $parallel_handler);
- #- read parallel configuration
- foreach (cat_("/etc/urpmi/parallel.cfg")) {
- chomp; s/#.*$//; s/^\s*//; s/\s*$//;
- /\s*([^:]*):(.*)/ or $urpm->{error}(N("unable to parse \"%s\" in file [%s]", $_, "/etc/urpmi/parallel.cfg")), next;
- $1 eq $options{parallel} and $parallel_options = ($parallel_options && "\n") . $2;
- }
- #- if a configuration option has been found, use it; else fatal error.
- if ($parallel_options) {
- foreach my $dir (grep { -d $_ } map { "$_/urpm" } @INC) {
- my $dh = $urpm->opendir_safe($dir);
- if ($dh) {
- while (defined ($_ = readdir $dh)) { #- load parallel modules
- /parallel.*\.pm$/ && -f "$dir/$_" or next;
- $urpm->{log}->(N("examining parallel handler in file [%s]", "$dir/$_"));
- eval { require "$dir/$_"; $parallel_handler = $urpm->handle_parallel_options($parallel_options) };
- $parallel_handler and last;
- }
- closedir $dh;
- }
- $parallel_handler and last;
- }
- }
- if ($parallel_handler) {
- if ($parallel_handler->{nodes}) {
- $urpm->{log}->(N("found parallel handler for nodes: %s", join(', ', keys %{$parallel_handler->{nodes}})));
- }
- if (!$options{media} && $parallel_handler->{media}) {
- $options{media} = $parallel_handler->{media};
- $urpm->{log}->(N("using associated media for parallel mode: %s", $options{media}));
- }
- $urpm->{parallel_handler} = $parallel_handler;
- } else {
- $urpm->{fatal}(1, N("unable to use parallel option \"%s\"", $options{parallel}));
+ _configure_parallel($urpm, $options{parallel});
+
+ if (!$options{media} && $urpm->{parallel_handler}{media}) {
+ $options{media} = $urpm->{parallel_handler}{media};
+ $urpm->{log}->(N("using associated media for parallel mode: %s", $options{media}));
}
} else {
#- parallel is exclusive against root options.
@@ -529,25 +616,16 @@ sub configure {
}
if ($options{excludemedia}) {
delete $_->{modified} foreach @{$urpm->{media} || []};
- $urpm->select_media(split /,/, $options{excludemedia});
- foreach (grep { $_->{modified} } @{$urpm->{media} || []}) {
+ foreach (select_media_by_name($urpm, [ split /,/, $options{excludemedia} ], {})) {
+ $_->{modified} = 1;
#- this is only a local ignore that will not be saved.
$_->{tempignore} = $_->{ignore} = 1;
}
}
if ($options{sortmedia}) {
- delete $_->{modified} foreach @{$urpm->{media} || []};
- my @oldmedia = @{$urpm->{media} || []};
- my @newmedia;
- foreach (split /,/, $options{sortmedia}) {
- $urpm->select_media($_);
- push @newmedia, grep { $_->{modified} } @oldmedia;
- @oldmedia = grep { !$_->{modified} } @oldmedia;
- }
- #- anything not selected should be added here, as it's after the selected ones.
- $urpm->{media} = [ @newmedia, @oldmedia ];
- #- forget remaining modified flags.
- delete $_->{modified} foreach @{$urpm->{media} || []};
+ my @sorted_media = map { select_media_by_name($urpm, [$_], {}) } split(/,/, $options{sortmedia});
+ my @remaining = difference2($urpm->{media}, \@sorted_media);
+ $urpm->{media} = [ @sorted_media, @remaining ];
}
unless ($options{nodepslist}) {
my $second_pass;
@@ -556,19 +634,15 @@ sub configure {
our $currentmedia = $_; #- hack for urpmf
delete @$_{qw(start end)};
if ($_->{virtual}) {
- my $path = $_->{url} =~ m!^(?:file:/*)?(/[^/].*[^/])/*\Z! && $1;
- if ($path) {
+ if (file_from_file_url($_->{url})) {
if ($_->{synthesis}) {
- $urpm->{log}(N("examining synthesis file [%s]", "$path/$_->{with_hdlist}"));
- ($_->{start}, $_->{end}) = $urpm->parse_synthesis(
- "$path/$_->{with_hdlist}", callback => $options{callback});
+ _parse_synthesis($urpm, $_,
+ hdlist_or_synthesis_for_virtual_medium($_), callback => $options{callback});
} else {
- $urpm->{log}(N("examining hdlist file [%s]", "$path/$_->{with_hdlist}"));
#- we'll need a second pass
defined $second_pass or $second_pass = 1;
- ($_->{start}, $_->{end}) = $urpm->parse_hdlist(
- "$path/$_->{with_hdlist}",
- packing => 1,
+ _parse_hdlist($urpm, $_,
+ hdlist_or_synthesis_for_virtual_medium($_),
callback => $options{call_back_only_once} && $second_pass ? undef : $options{callback},
);
}
@@ -577,40 +651,32 @@ sub configure {
$_->{ignore} = 1;
}
} else {
- if ($options{hdlist} && file_size("$urpm->{statedir}/$_->{hdlist}") > 32) {
- $urpm->{log}(N("examining hdlist file [%s]", "$urpm->{statedir}/$_->{hdlist}"));
- ($_->{start}, $_->{end}) = $urpm->parse_hdlist(
- "$urpm->{statedir}/$_->{hdlist}",
- packing => 1,
+ if ($options{hdlist} && file_size(statedir_hdlist($urpm, $_)) > 32) {
+ _parse_hdlist($urpm, $_, statedir_hdlist($urpm, $_),
callback => $options{callback},
);
} else {
- $urpm->{log}(N("examining synthesis file [%s]", "$urpm->{statedir}/synthesis.$_->{hdlist}"));
- ($_->{start}, $_->{end}) = $urpm->parse_synthesis(
- "$urpm->{statedir}/synthesis.$_->{hdlist}",
+ _parse_synthesis($urpm, $_,
+ statedir_synthesis($urpm, $_),
callback => $options{callback},
);
- unless (defined $_->{start} && defined $_->{end}) {
- $urpm->{log}(N("examining hdlist file [%s]", "$urpm->{statedir}/$_->{hdlist}"));
- ($_->{start}, $_->{end}) = $urpm->parse_hdlist("$urpm->{statedir}/$_->{hdlist}",
- packing => 1,
+ if (!is_valid_medium($_)) {
+ _parse_hdlist($urpm, $_, statedir_hdlist($urpm, $_),
callback => $options{callback},
);
}
}
}
unless ($_->{ignore}) {
- if (defined $_->{start} && defined $_->{end}) {
+ _check_after_reading_hdlist_or_synthesis($urpm, $_);
+ }
+ unless ($_->{ignore}) {
if ($_->{searchmedia}) {
($urpm->{searchmedia}{start}, $urpm->{searchmedia}{end}) = ($_->{start}, $_->{end});
$urpm->{log}(N("Search start: %s end: %s",
$urpm->{searchmedia}{start}, $urpm->{searchmedia}{end}));
delete $_->{searchmedia};
}
- } else {
- $urpm->{error}(N("problem reading hdlist or synthesis file of medium \"%s\"", $_->{name}));
- $_->{ignore} = 1;
- }
}
}
} while $second_pass && do {
@@ -650,12 +716,11 @@ sub configure {
}
if ($options{bug}) {
#- and a dump of rpmdb itself as synthesis file.
- my $db = URPM::DB::open($options{root});
+ my $db = db_open_or_die($urpm, $options{root});
my $sig_handler = sub { undef $db; exit 3 };
local $SIG{INT} = $sig_handler;
local $SIG{QUIT} = $sig_handler;
- $db or $urpm->{fatal}(9, N("unable to open rpmdb"));
open my $rpmdb, "| " . ($ENV{LD_LOADER} || '') . " gzip -9 >'$options{bug}/rpmdb.cz'"
or $urpm->syserror("Can't fork", "gzip");
$db->traverse(sub {
@@ -676,8 +741,8 @@ sub add_medium {
my ($urpm, $name, $url, $with_hdlist, %options) = @_;
#- make sure configuration has been read.
- $urpm->{media} or $urpm->read_config;
- $options{nolock} or $urpm->exlock_urpmi_db;
+ $urpm->{media} or die "caller should have used ->read_config or ->configure first";
+ $urpm->lock_urpmi_db('exclusive') if !$options{nolock};
#- if a medium with that name has already been found, we have to exit now
my $medium;
@@ -685,16 +750,11 @@ sub add_medium {
my $i = $options{index_name};
do {
++$i;
- undef $medium;
- foreach (@{$urpm->{media}}) {
- $_->{name} eq $name . $i and $medium = $_;
- }
+ $medium = name2medium($urpm, $name . $i);
} while $medium;
$name .= $i;
} else {
- foreach (@{$urpm->{media}}) {
- $_->{name} eq $name and $medium = $_;
- }
+ $medium = name2medium($urpm, $name);
}
$medium and $urpm->{fatal}(5, N("medium \"%s\" already exists", $medium->{name}));
@@ -703,17 +763,16 @@ sub add_medium {
#- creating the medium info.
$medium = { name => $name, url => $url, update => $options{update}, modified => 1, ignore => $options{ignore} };
if ($options{virtual}) {
- $url =~ m!^(?:file:)?/! or $urpm->{fatal}(1, N("virtual medium needs to be local"));
+ file_from_file_url($url) or $urpm->{fatal}(1, N("virtual medium needs to be local"));
$medium->{virtual} = 1;
} else {
$medium->{hdlist} = "hdlist.$name.cz";
$medium->{list} = "list.$name";
- #- check if the medium is using a local or a removable medium.
- $url =~ m!^(?:(removable[^:]*|file):/)?(/.*)! and $urpm->probe_removable_device($medium);
+ $urpm->probe_removable_device($medium);
}
#- local media have priority, other are added at the end.
- if ($url =~ m!^(?:file:)?/!) {
+ if (file_from_file_url($url)) {
$medium->{priority} = 0.5;
} else {
$medium->{priority} = 1 + @{$urpm->{media}};
@@ -735,16 +794,16 @@ sub add_medium {
$urpm->write_config;
delete $urpm->{media};
$urpm->read_config(nocheck_access => 1);
- #- Remember that the database has been modified and base files need to
- #- be updated. This will be done automatically by transferring the
- #- "modified" flag from medium to global.
- $_->{name} eq $name and $_->{modified} = 1 foreach @{$urpm->{media}};
- $urpm->{modified} = 1;
+
+ #- need getting the fresh datastructure after read_config
+ $medium = name2medium($urpm, $name); #- need getting the fresh datastructure after read_config
+
+ #- Remember that the database has been modified and base files need to be updated.
+ $medium->{modified} = 1;
+ $urpm->{md5sum_modified} = 1;
}
if ($has_password) {
- foreach (grep { $_->{name} eq $name } @{$urpm->{media}}) {
- $_->{url} = $url;
- }
+ $medium->{url} = $url;
}
$options{nolock} or $urpm->unlock_urpmi_db;
@@ -763,11 +822,11 @@ sub add_distrib_media {
my ($urpm, $name, $url, %options) = @_;
#- make sure configuration has been read.
- $urpm->{media} or $urpm->read_config;
+ $urpm->{media} or die "caller should have used ->read_config or ->configure first";
my $distribconf;
- if (my ($dir) = $url =~ m!^(?:removable[^:]*:/|file:/)?(/.*)!) {
+ if (my $dir = file_from_local_url($url)) {
$urpm->try_mounting($dir)
or $urpm->{error}(N("unable to mount the distribution medium")), return ();
$distribconf = MDV::Distribconf->new($dir, undef);
@@ -781,17 +840,9 @@ sub add_distrib_media {
eval {
$urpm->{log}(N("retrieving media.cfg file..."));
- $urpm->{sync}(
- {
- dir => "$urpm->{cachedir}/partial",
- quiet => 1,
- limit_rate => $options{limit_rate},
- compress => $options{compress},
- retry => $urpm->{options}{retry},
- proxy => get_proxy(),
- },
- reduce_pathname($distribconf->getfullpath(undef, 'infodir') . '/media.cfg'),
- );
+ sync_webfetch($urpm, undef,
+ [ reduce_pathname($distribconf->getfullpath(undef, 'infodir') . '/media.cfg') ],
+ \%options, quiet => 1);
$urpm->{log}(N("...retrieving done"));
};
$@ and $urpm->{error}(N("...retrieving failed: %s", $@));
@@ -854,56 +905,63 @@ sub add_distrib_media {
return @newnames;
}
+#- deprecated, use select_media_by_name instead
sub select_media {
my $urpm = shift;
my $options = {};
if (ref $_[0]) { $options = shift }
- my %media; @media{@_} = ();
-
- foreach (@{$urpm->{media}}) {
- if (exists($media{$_->{name}})) {
- $media{$_->{name}} = 1; #- keep in mind this one has been selected.
- #- select medium by setting the modified flag, do not check ignore.
- $_->{modified} = 1;
- }
+ foreach (select_media_by_name($urpm, [ @_ ], $options)) {
+ #- select medium by setting the modified flag, do not check ignore.
+ $_->{modified} = 1;
}
+}
+
+sub select_media_by_name {
+ my ($urpm, $names, $options) = @_;
+
+ my %wanted = map { $_ => 1 } @$names;
+
+ #- first the exact matches
+ my @l = grep { delete $wanted{$_->{name}} } @{$urpm->{media}};
#- check if some arguments don't correspond to the medium name.
#- in such case, try to find the unique medium (or list candidate
#- media found).
- foreach (keys %media) {
- unless ($media{$_}) {
- my $q = quotemeta;
- my (@found, @foundi);
- my $regex = $options->{strict_match} ? qr/^$q$/ : qr/$q/;
- my $regexi = $options->{strict_match} ? qr/^$q$/i : qr/$q/i;
- foreach my $medium (@{$urpm->{media}}) {
- $medium->{name} =~ $regex and push @found, $medium;
- $medium->{name} =~ $regexi and push @foundi, $medium;
- }
- if (@found == 1) {
- $found[0]{modified} = 1;
- } elsif (@foundi == 1) {
- $foundi[0]{modified} = 1;
- } elsif (@found == 0 && @foundi == 0) {
- $urpm->{error}(N("trying to select nonexistent medium \"%s\"", $_));
- } else { #- several elements in found and/or foundi lists.
- $urpm->{log}(N("selecting multiple media: %s", join(", ", map { qq("$_->{name}") } (@found ? @found : @foundi))));
- #- changed behaviour to select all occurences by default.
- foreach (@found ? @found : @foundi) {
- $_->{modified} = 1;
- }
+ foreach (keys %wanted) {
+ my $q = quotemeta;
+ my (@found, @foundi);
+ my $regex = $options->{strict_match} ? qr/^$q$/ : qr/$q/;
+ my $regexi = $options->{strict_match} ? qr/^$q$/i : qr/$q/i;
+ foreach my $medium (@{$urpm->{media}}) {
+ $medium->{name} =~ $regex and push @found, $medium;
+ $medium->{name} =~ $regexi and push @foundi, $medium;
+ }
+ @found = @foundi if !@found;
+
+ if (@found == 0) {
+ $urpm->{error}(N("trying to select nonexistent medium \"%s\"", $_));
+ } else {
+ if (@found > 1) {
+ $urpm->{log}(N("selecting multiple media: %s", join(", ", map { qq("$_->{name}") } @found)));
}
+ #- changed behaviour to select all occurences by default.
+ push @l, @found;
}
}
+ @l;
}
+#- deprecated, use remove_media instead
sub remove_selected_media {
my ($urpm) = @_;
- my @result;
- foreach (@{$urpm->{media}}) {
- if ($_->{modified}) {
+ remove_media($urpm, [ grep { $_->{modified} } @{$urpm->{media}} ]);
+}
+
+sub remove_media {
+ my ($urpm, $to_remove) = @_;
+
+ foreach (@$to_remove) {
$urpm->{log}(N("removing medium \"%s\"", $_->{name}));
#- mark to re-write configuration.
@@ -917,13 +975,9 @@ sub remove_selected_media {
#- remove proxy settings for this media
urpm::download::remove_proxy_media($_->{name});
- } else {
- push @result, $_; #- not removed so keep it
- }
}
- #- restore newer media list.
- $urpm->{media} = \@result;
+ $urpm->{media} = [ difference2($urpm->{media}, $to_remove) ];
}
#- return list of synthesis or hdlist reference to probe.
@@ -947,50 +1001,83 @@ sub _probe_with_try_list {
@probe;
}
+sub may_reconfig_urpmi {
+ my ($urpm, $medium, $options) = @_;
+
+ my $f;
+ if (my $dir = file_from_file_url($medium->{url})) {
+ $f = reduce_pathname("$dir/reconfig.urpmi");
+ } else {
+ unlink($f = "$urpm->{cachedir}/partial/reconfig.urpmi");
+ eval {
+ sync_webfetch($urpm, $medium, [ reduce_pathname("$medium->{url}/reconfig.urpmi") ],
+ $options, quiet => 1);
+ };
+ }
+ if (-s $f) {
+ reconfig_urpmi($urpm, $f, $medium->{name});
+ }
+ unlink $f if !file_from_file_url($medium->{url});
+}
+
#- read a reconfiguration file for urpmi, and reconfigure media accordingly
#- $rfile is the reconfiguration file (local), $name is the media name
+#-
+#- the format is similar to the RewriteRule of mod_rewrite, so:
+#- PATTERN REPLACEMENT [FLAG]
+#- where FLAG can be L or N
+#-
+#- example of reconfig.urpmi:
+#- # this is an urpmi reconfiguration file
+#- /cooker /cooker/$ARCH
sub reconfig_urpmi {
my ($urpm, $rfile, $name) = @_;
- my @replacements;
- my @reconfigurable = qw(url with_hdlist clear_url);
- my $reconfigured = 0;
- my $fh = $urpm->open_safe("<", $rfile) or return undef;
+ -r $rfile or return;
+
$urpm->{log}(N("reconfiguring urpmi for media \"%s\"", $name));
+
+ my ($magic, @lines) = cat_($rfile);
#- the first line of reconfig.urpmi must be magic, to be sure it's not an error file
- my $magic = <$fh>;
$magic =~ /^# this is an urpmi reconfiguration file/ or return undef;
- local $_;
- while (<$fh>) {
+
+ my @replacements;
+ foreach (@lines) {
chomp;
s/^\s*//; s/#.*$//; s/\s*$//;
$_ or next;
my ($p, $r, $f) = split /\s+/, $_, 3;
- $f ||= 1;
- push @replacements, [ quotemeta $p, $r, $f ];
- }
- MEDIA:
- foreach my $medium (grep { $_->{name} eq $name } @{$urpm->{media}}) {
- my %orig = map { $_ => $medium->{$_} } @reconfigurable;
- URLS:
- foreach my $k (@reconfigurable) {
- foreach my $r (@replacements) {
- if ($medium->{$k} =~ s/$r->[0]/$r->[1]/) {
- $reconfigured = 1;
- #- Flags stolen from mod_rewrite: L(ast), N(ext)
- last if $r->[2] =~ /L/;
- redo URLS if $r->[2] =~ /N/;
+ push @replacements, [ quotemeta $p, $r, $f || 1 ];
+ }
+
+ my $reconfigured = 0;
+ my @reconfigurable = qw(url with_hdlist clear_url);
+
+ my $medium = name2medium($urpm, $name) or return;
+ my %orig = %$medium;
+
+ URLS:
+ foreach my $k (@reconfigurable) {
+ foreach my $r (@replacements) {
+ if ($medium->{$k} =~ s/$r->[0]/$r->[1]/) {
+ $reconfigured = 1;
+ #- Flags stolen from mod_rewrite: L(ast), N(ext)
+ if ($r->[2] =~ /L/) {
+ last;
+ } elsif ($r->[2] =~ /N/) { #- dangerous option
+ redo URLS;
}
}
- #- check that the new url exists before committing changes (local mirrors)
- if ($medium->{$k} =~ m!^(?:file:/*)?(/[^/].*[^/])/*\Z! && !-e $1) {
- $medium->{$k} = $orig{$k} foreach @reconfigurable;
- $reconfigured = 0;
- $urpm->{log}(N("...reconfiguration failed"));
- last MEDIA;
- }
+ }
+ #- check that the new url exists before committing changes (local mirrors)
+ my $file = file_from_local_url($medium->{$k});
+ if ($file && !-e $file) {
+ %$medium = %orig;
+ $reconfigured = 0;
+ $urpm->{log}(N("...reconfiguration failed"));
+ return;
}
}
- close $fh;
+
if ($reconfigured) {
$urpm->{log}(N("reconfiguration done"));
$urpm->write_config;
@@ -1004,9 +1091,9 @@ sub _guess_hdlist_suffix {
$suffix;
}
-sub _guess_pubkey_name {
+sub _hdlist_suffix {
my ($medium) = @_;
- return $medium->{with_hdlist} =~ /hdlist(.*?)(?:\.src)?\.cz$/ ? "pubkey$1" : 'pubkey';
+ $medium->{with_hdlist} =~ /hdlist(.*?)(?:\.src)?\.cz$/ ? $1 : '';
}
sub _update_media__when_not_modified {
@@ -1014,34 +1101,24 @@ sub _update_media__when_not_modified {
delete @$medium{qw(start end)};
if ($medium->{virtual}) {
- my ($path) = $medium->{url} =~ m!^(?:file:)?/*(/[^/].*[^/])/*\Z!;
- if ($path) {
- my $with_hdlist_file = "$path/$medium->{with_hdlist}";
+ if (file_from_file_url($medium->{url})) {
if ($medium->{synthesis}) {
- $urpm->{log}(N("examining synthesis file [%s]", $with_hdlist_file));
- ($medium->{start}, $medium->{end}) = $urpm->parse_synthesis($with_hdlist_file);
+ _parse_synthesis($urpm, $medium, hdlist_or_synthesis_for_virtual_medium($medium));
} else {
- $urpm->{log}(N("examining hdlist file [%s]", $with_hdlist_file));
- ($medium->{start}, $medium->{end}) = $urpm->parse_hdlist($with_hdlist_file, packing => 1);
+ _parse_hdlist($urpm, $medium, hdlist_or_synthesis_for_virtual_medium($medium));
}
} else {
$urpm->{error}(N("virtual medium \"%s\" is not local, medium ignored", $medium->{name}));
$medium->{ignore} = 1;
}
} else {
- $urpm->{log}(N("examining synthesis file [%s]", "$urpm->{statedir}/synthesis.$medium->{hdlist}"));
- ($medium->{start}, $medium->{end}) = $urpm->parse_synthesis("$urpm->{statedir}/synthesis.$medium->{hdlist}");
- unless (defined $medium->{start} && defined $medium->{end}) {
- $urpm->{log}(N("examining hdlist file [%s]", "$urpm->{statedir}/$medium->{hdlist}"));
- ($medium->{start}, $medium->{end}) = $urpm->parse_hdlist("$urpm->{statedir}/$medium->{hdlist}", packing => 1);
+ _parse_synthesis($urpm, $medium, statedir_synthesis($urpm, $medium));
+ if (!is_valid_medium($medium)) {
+ _parse_hdlist($urpm, $medium, statedir_hdlist($urpm, $medium));
}
}
unless ($medium->{ignore}) {
- unless (defined $medium->{start} && defined $medium->{end}) {
- #- this is almost a fatal error, ignore it by default?
- $urpm->{error}(N("problem reading hdlist or synthesis file of medium \"%s\"", $medium->{name}));
- $medium->{ignore} = 1;
- }
+ _check_after_reading_hdlist_or_synthesis($urpm, $medium);
}
}
@@ -1051,34 +1128,25 @@ sub _update_media__virtual {
if ($medium->{with_hdlist} && -e $with_hdlist_dir) {
delete @$medium{qw(start end)};
if ($medium->{synthesis}) {
- $urpm->{log}(N("examining synthesis file [%s]", $with_hdlist_dir));
- ($medium->{start}, $medium->{end}) = $urpm->parse_synthesis($with_hdlist_dir);
+ _parse_synthesis($urpm, $medium, $with_hdlist_dir);
delete $medium->{modified};
$medium->{synthesis} = 1;
- $urpm->{modified} = 1;
- unless (defined $medium->{start} && defined $medium->{end}) {
- $urpm->{log}(N("examining hdlist file [%s]", $with_hdlist_dir));
- ($medium->{start}, $medium->{end}) = $urpm->parse_hdlist($with_hdlist_dir, packing => 1);
+ $urpm->{md5sum_modified} = 1;
+ if (!is_valid_medium($medium)) {
+ _parse_hdlist($urpm, $medium, $with_hdlist_dir);
delete @$medium{qw(modified synthesis)};
- $urpm->{modified} = 1;
}
} else {
- $urpm->{log}(N("examining hdlist file [%s]", $with_hdlist_dir));
- ($medium->{start}, $medium->{end}) = $urpm->parse_hdlist($with_hdlist_dir, packing => 1);
+ _parse_hdlist($urpm, $medium, $with_hdlist_dir);
delete @$medium{qw(modified synthesis)};
- $urpm->{modified} = 1;
- unless (defined $medium->{start} && defined $medium->{end}) {
- $urpm->{log}(N("examining synthesis file [%s]", $with_hdlist_dir));
- ($medium->{start}, $medium->{end}) = $urpm->parse_synthesis($with_hdlist_dir);
+ $urpm->{md5sum_modified} = 1;
+ if (!is_valid_medium($medium)) {
+ _parse_synthesis($urpm, $medium, $with_hdlist_dir);
delete $medium->{modified};
$medium->{synthesis} = 1;
- $urpm->{modified} = 1;
}
}
- unless (defined $medium->{start} && defined $medium->{end}) {
- $urpm->{error}(N("problem reading hdlist or synthesis file of medium \"%s\"", $medium->{name}));
- $medium->{ignore} = 1;
- }
+ _check_after_reading_hdlist_or_synthesis($urpm, $medium);
} else {
$urpm->{error}(N("virtual medium \"%s\" should have valid source hdlist or synthesis, medium ignored",
$medium->{name}));
@@ -1092,7 +1160,7 @@ sub generate_media_names {
#- make sure names files are regenerated.
foreach (@{$urpm->{media}}) {
unlink "$urpm->{statedir}/names.$_->{name}";
- if (defined $_->{start} && defined $_->{end}) {
+ if (is_valid_medium($_)) {
my $fh = $urpm->open_safe(">", "$urpm->{statedir}/names.$_->{name}");
if ($fh) {
foreach ($_->{start} .. $_->{end}) {
@@ -1110,807 +1178,836 @@ sub generate_media_names {
}
}
-#- Update the urpmi database w.r.t. the current configuration.
-#- Takes care of modifications, and tries some tricks to bypass
-#- the recomputation of base files.
-#- Recognized options :
-#- all : all medias are being rebuilt
-#- callback : UI callback
-#- compress : use compressed download (for rsync)
-#- forcekey : force retrieval of pubkey
-#- force : try to force rebuilding base files (1) or hdlist from rpm files (2)
-#- limit_rate : download limit rate
-#- noclean : keep old files in the header cache directory
-#- nolock : don't lock the urpmi database
-#- nomd5sum : don't verify MD5SUM of retrieved files
-#- nopubkey : don't use rpm pubkeys
-#- norebuild : don't try to rebuild hdlists from rpm headers
-#- probe_with : probe synthesis or hdlist (or none)
-#- quiet : download hdlists quietly
-#- ratio : use this compression ratio (with gzip, default is 4)
-sub update_media {
- my ($urpm, %options) = @_;
- my $clean_cache = !$options{noclean};
- my $second_pass;
- $urpm->{media} or return; # verify that configuration has been read
+sub _read_existing_synthesis_and_hdlist_if_same_time_and_msize {
+ my ($urpm, $medium, $basename) = @_;
- my $nopubkey = $options{nopubkey} || $urpm->{options}{nopubkey};
- #- get gpg-pubkey signature.
- if (!$nopubkey) {
- $urpm->exlock_rpm_db;
- $urpm->{keys} or $urpm->parse_pubkeys(root => $urpm->{root});
+ same_size_and_mtime("$urpm->{cachedir}/partial/$basename",
+ statedir_hdlist($urpm, $medium)) or return;
+
+ unlink "$urpm->{cachedir}/partial/$basename";
+
+ _read_existing_synthesis_and_hdlist($urpm, $medium);
+
+ 1;
+}
+
+sub _read_existing_synthesis_and_hdlist_if_same_md5sum {
+ my ($urpm, $medium, $retrieved_md5sum) = @_;
+
+ #- if an existing hdlist or synthesis file has the same md5sum, we assume the
+ #- files are the same.
+ #- if local md5sum is the same as distant md5sum, this means there is no need to
+ #- download hdlist or synthesis file again.
+ $retrieved_md5sum && $medium->{md5sum} eq $retrieved_md5sum or return;
+
+ unlink "$urpm->{cachedir}/partial/" . basename($medium->{with_hdlist});
+
+ _read_existing_synthesis_and_hdlist($urpm, $medium);
+
+ 1;
+}
+
+sub _read_existing_synthesis_and_hdlist {
+ my ($urpm, $medium) = @_;
+
+ $urpm->{log}(N("medium \"%s\" is up-to-date", $medium->{name}));
+
+ #- the medium is now considered not modified.
+ $medium->{modified} = 0;
+ #- XXX we could link the new hdlist to the old one.
+ #- (However links need to be managed. see bug #12391.)
+ #- as previously done, just read synthesis file here, this is enough.
+ _parse_synthesis($urpm, $medium, statedir_synthesis($urpm, $medium));
+ if (!is_valid_medium($medium)) {
+ _parse_hdlist($urpm, $medium, statedir_hdlist($urpm, $medium));
+ _check_after_reading_hdlist_or_synthesis($urpm, $medium);
}
- #- lock database if allowed.
- $options{nolock} or $urpm->exlock_urpmi_db;
- #- examine each medium to see if one of them needs to be updated.
- #- if this is the case and if not forced, try to use a pre-calculated
- #- hdlist file, else build it from rpm files.
- $urpm->clean;
+ 1;
+}
- my %media_redone;
- MEDIA:
- foreach my $medium (@{$urpm->{media}}) {
- $medium->{ignore} and next MEDIA;
+sub _parse_hdlist {
+ my ($urpm, $medium, $hdlist_file, %args) = @_;
- $options{forcekey} and delete $medium->{'key-ids'};
+ $urpm->{log}(N("examining hdlist file [%s]", $hdlist_file));
+ ($medium->{start}, $medium->{end}) = $urpm->parse_hdlist($hdlist_file, packing => 1, %args);
+}
- #- we should create the associated synthesis file if it does not already exist...
- file_size("$urpm->{statedir}/synthesis.$medium->{hdlist}") > 32
- or $medium->{modified_synthesis} = 1;
+sub _parse_synthesis {
+ my ($urpm, $medium, $synthesis_file, %args) = @_;
- #- if we're rebuilding all media, mark them as modified (except removable ones)
- $medium->{modified} ||= $options{all} && $medium->{url} !~ m!^removable://!;
- #- don't ever update static media
- $medium->{static} and $medium->{modified} = 0;
-
- unless ($medium->{modified}) {
- #- the medium is not modified, but to compute dependencies,
- #- we still need to read it and all synthesis will be written if
- #- an unresolved provides is found.
- #- to speed up the process, we only read the synthesis at the beginning.
- _update_media__when_not_modified($urpm, $medium);
- next;
- }
+ $urpm->{log}(N("examining synthesis file [%s]", $synthesis_file));
+ ($medium->{start}, $medium->{end}) = $urpm->parse_synthesis($synthesis_file, %args);
+}
- #- list of rpm files for this medium, only available for local medium where
- #- the source hdlist is not used (use force).
- my ($prefix, $dir, $error, $retrieved_md5sum, @files);
+sub is_valid_medium {
+ my ($medium) = @_;
+ defined $medium->{start} && defined $medium->{end};
+}
- #- always delete a remaining list file or pubkey file in cache.
- foreach (qw(list pubkey)) {
- unlink "$urpm->{cachedir}/partial/$_";
- }
+sub _check_after_reading_hdlist_or_synthesis {
+ my ($urpm, $medium) = @_;
- #- check if the medium is using a local or a removable medium.
- if (($prefix, $dir) = $medium->{url} =~ m!^(?:(removable[^:]*|file):/)?(/.*)!) {
- $prefix ||= 'file';
- #- check for a reconfig.urpmi file (if not already reconfigured)
- if (!$media_redone{$medium->{name}} && !$medium->{noreconfigure}) {
- my $reconfig_urpmi = reduce_pathname("$dir/reconfig.urpmi");
- if (-s $reconfig_urpmi && $urpm->reconfig_urpmi($reconfig_urpmi, $medium->{name})) {
- $media_redone{$medium->{name}} = 1;
- redo MEDIA;
- }
- }
+ if (!is_valid_medium($medium)) {
+ $urpm->{error}(N("problem reading hdlist or synthesis file of medium \"%s\"", $medium->{name}));
+ $medium->{ignore} = 1;
+ }
+}
- #- try to figure a possible hdlist_path (or parent directory of searched directory).
- #- this is used to probe for a possible hdlist file.
- my $with_hdlist_dir = reduce_pathname($dir . ($medium->{with_hdlist} ? "/$medium->{with_hdlist}" : "/.."));
+sub db_open_or_die {
+ my ($urpm, $root, $b_force) = @_;
- #- the directory given does not exist and may be accessible
- #- by mounting some other directory. Try to figure it out and mount
- #- everything that might be necessary.
- -d $dir or $urpm->try_mounting(
- $options{force} < 2 && ($options{probe_with} || $medium->{with_hdlist})
- ? $with_hdlist_dir : $dir,
- #- in case of an iso image, pass its name
- is_iso($medium->{removable}) && $medium->{removable},
- ) or $urpm->{error}(N("unable to access medium \"%s\",
-this could happen if you mounted manually the directory when creating the medium.", $medium->{name})), next;
-
- #- try to probe for possible with_hdlist parameter, unless
- #- it is already defined (and valid).
- if ($options{probe_with} && (!$medium->{with_hdlist} || ! -e "$dir/$medium->{with_hdlist}")) {
- foreach (_probe_with_try_list(_guess_hdlist_suffix($dir), $options{probe_with})) {
- if (file_size("$dir/$_") > 32) {
- $medium->{with_hdlist} = $_;
- last;
- }
- }
- #- redo...
- $with_hdlist_dir = reduce_pathname($dir . ($medium->{with_hdlist} ? "/$medium->{with_hdlist}" : "/.."));
+ my $db = URPM::DB::open($root, $b_force)
+ or $urpm->{fatal}(9, N("unable to open rpmdb"));
+
+ $db;
+}
+
+sub _update_media__sync_file {
+ my ($urpm, $medium, $name, $options) = @_;
+
+ my $local_name = $name . _hdlist_suffix($medium);
+
+ foreach (reduce_pathname("$medium->{url}/$medium->{with_hdlist}/../$local_name"),
+ reduce_pathname("$medium->{url}/$name")) {
+ eval {
+ sync_webfetch($urpm, $medium, [$_], $options, quiet => 1);
+
+ if ($local_name ne $name && -s "$urpm->{cachedir}/partial/$local_name") {
+ rename("$urpm->{cachedir}/partial/$local_name",
+ "$urpm->{cachedir}/partial/$name");
}
+ };
+ $@ and unlink "$urpm->{cachedir}/partial/$name";
+ -s "$urpm->{cachedir}/partial/$name" and last;
+ }
+}
- if ($medium->{virtual}) {
- #- syncing a virtual medium is very simple, just try to read the file in order to
- #- determine its type, once a with_hdlist has been found (but is mandatory).
- _update_media__virtual($urpm, $medium, $with_hdlist_dir);
- }
- #- try to get the description if it has been found.
- unlink "$urpm->{statedir}/descriptions.$medium->{name}";
- my $description_file = "$dir/media_info/descriptions"; #- new default location
- -e $description_file or $description_file = "$dir/../descriptions";
- if (-e $description_file) {
- $urpm->{log}(N("copying description file of \"%s\"...", $medium->{name}));
- urpm::util::copy($description_file, "$urpm->{statedir}/descriptions.$medium->{name}")
- ? $urpm->{log}(N("...copying done"))
- : do { $urpm->{error}(N("...copying failed")); $medium->{ignore} = 1 };
- chown 0, 0, "$urpm->{statedir}/descriptions.$medium->{name}";
- }
-
- #- examine if a distant MD5SUM file is available.
- #- this will only be done if $with_hdlist is not empty in order to use
- #- an existing hdlist or synthesis file, and to check if download was good.
- #- if no MD5SUM is available, do it as before...
- #- we can assume at this point a basename is existing, but it needs
- #- to be checked for being valid, nothing can be deduced if no MD5SUM
- #- file is present.
- my $basename = basename($with_hdlist_dir);
+sub recursive_find_rpm_files {
+ my ($dir) = @_;
- unless ($medium->{virtual}) {
- if ($medium->{with_hdlist}) {
- if (!$options{nomd5sum} && file_size(reduce_pathname("$with_hdlist_dir/../MD5SUM")) > 32) {
- recompute_local_md5sum($urpm, $medium, $options{force});
- if ($medium->{md5sum}) {
- $retrieved_md5sum = parse_md5sum($urpm, reduce_pathname("$with_hdlist_dir/../MD5SUM"), $basename);
- #- If an existing hdlist or synthesis file has the same md5sum, we assume
- #- the files are the same.
- #- If the local md5sum is the same as the distant md5sum, this means
- #- that there is no need to download the hdlist or synthesis file again.
- if (defined $retrieved_md5sum && $medium->{md5sum} eq $retrieved_md5sum) {
- unlink "$urpm->{cachedir}/partial/$basename";
- #- the medium is now considered not modified.
- $medium->{modified} = 0;
- #- XXX we could link the new hdlist to the old one.
- #- (However links need to be managed. see bug #12391.)
- #- as previously done, just read synthesis file here, this is enough.
- $urpm->{log}(N("examining synthesis file [%s]",
- "$urpm->{statedir}/synthesis.$medium->{hdlist}"));
- ($medium->{start}, $medium->{end}) =
- $urpm->parse_synthesis("$urpm->{statedir}/synthesis.$medium->{hdlist}");
- unless (defined $medium->{start} && defined $medium->{end}) {
- $urpm->{log}(N("examining hdlist file [%s]", "$urpm->{statedir}/$medium->{hdlist}"));
- ($medium->{start}, $medium->{end}) =
- $urpm->parse_hdlist("$urpm->{statedir}/$medium->{hdlist}", packing => 1);
- unless (defined $medium->{start} && defined $medium->{end}) {
- $urpm->{error}(N("problem reading hdlist or synthesis file of medium \"%s\"",
- $medium->{name}));
- $medium->{ignore} = 1;
- }
- }
- }
- $medium->{modified} or next MEDIA;
- }
- }
+ my %f;
+ local $_; #- help perl_checker not warning "undeclared $_" in wanted callback below
+ File::Find::find(
+ {
+ wanted => sub { -f $_ && /\.rpm$/ and $f{"$File::Find::dir/$_"} = 1 },
+ follow_skip => 2,
+ follow_fast => 1,
+ },
+ $dir,
+ );
+ keys %f;
+}
- #- if the source hdlist is present and we are not forcing using rpm files
- if ($options{force} < 2 && -e $with_hdlist_dir) {
- unlink "$urpm->{cachedir}/partial/$medium->{hdlist}";
- $urpm->{log}(N("copying source hdlist (or synthesis) of \"%s\"...", $medium->{name}));
- $options{callback} and $options{callback}('copy', $medium->{name});
- if (urpm::util::copy($with_hdlist_dir, "$urpm->{cachedir}/partial/$medium->{hdlist}")) {
- $options{callback} and $options{callback}('done', $medium->{name});
- $urpm->{log}(N("...copying done"));
- chown 0, 0, "$urpm->{cachedir}/partial/$medium->{hdlist}";
- } else {
- $options{callback} and $options{callback}('failed', $medium->{name});
- #- force error, reported afterwards
- unlink "$urpm->{cachedir}/partial/$medium->{hdlist}";
- }
- }
+sub clean_dir {
+ my ($dir) = @_;
- file_size("$urpm->{cachedir}/partial/$medium->{hdlist}") > 32 or
- $error = 1, $urpm->{error}(N("copy of [%s] failed (file is suspiciously small)",
- "$urpm->{cachedir}/partial/$medium->{hdlist}"));
+ require File::Path;
+ File::Path::rmtree([$dir]);
+ mkdir $dir, 0755;
+}
+
+sub _update_medium_first_pass__local {
+ my ($urpm, $medium, $second_pass, $clean_cache, $retrieved_md5sum, $rpm_files, $options) = @_;
+
+ my $dir = file_from_local_url($medium->{url});
+
+ #- try to figure a possible hdlist_path (or parent directory of searched directory).
+ #- this is used to probe for a possible hdlist file.
+ my $with_hdlist_dir = reduce_pathname($dir . ($medium->{with_hdlist} ? "/$medium->{with_hdlist}" : "/.."));
+
+ #- the directory given does not exist and may be accessible
+ #- by mounting some other directory. Try to figure it out and mount
+ #- everything that might be necessary.
+ -d $dir or $urpm->try_mounting(
+ $options->{force} < 2 && ($options->{probe_with} || $medium->{with_hdlist})
+ ? $with_hdlist_dir : $dir,
+ #- in case of an iso image, pass its name
+ is_iso($medium->{removable}) && $medium->{removable},
+ ) or $urpm->{error}(N("unable to access medium \"%s\",
+this could happen if you mounted manually the directory when creating the medium.", $medium->{name})), return 'unmodified';
+
+ #- try to probe for possible with_hdlist parameter, unless
+ #- it is already defined (and valid).
+ if ($options->{probe_with} && (!$medium->{with_hdlist} || ! -e "$dir/$medium->{with_hdlist}")) {
+ foreach (_probe_with_try_list(_guess_hdlist_suffix($dir), $options->{probe_with})) {
+ if (file_size("$dir/$_") > 32) {
+ $medium->{with_hdlist} = $_;
+ last;
+ }
+ }
+ #- redo...
+ $with_hdlist_dir = reduce_pathname($dir . ($medium->{with_hdlist} ? "/$medium->{with_hdlist}" : "/.."));
+ }
- #- keep checking md5sum of file just copied ! (especially on nfs or removable device).
- if (!$error && $retrieved_md5sum) {
- $urpm->{log}(N("computing md5sum of copied source hdlist (or synthesis)"));
- md5sum("$urpm->{cachedir}/partial/$medium->{hdlist}") eq $retrieved_md5sum or
- $error = 1, $urpm->{error}(N("copy of [%s] failed (md5sum mismatch)", $with_hdlist_dir));
- }
+ if ($medium->{virtual}) {
+ #- syncing a virtual medium is very simple, just try to read the file in order to
+ #- determine its type, once a with_hdlist has been found (but is mandatory).
+ _update_media__virtual($urpm, $medium, $with_hdlist_dir);
+ }
+ #- try to get the description if it has been found.
+ unlink "$urpm->{statedir}/descriptions.$medium->{name}";
+ my $description_file = "$dir/media_info/descriptions"; #- new default location
+ -e $description_file or $description_file = "$dir/../descriptions";
+ if (-e $description_file) {
+ $urpm->{log}(N("copying description file of \"%s\"...", $medium->{name}));
+ urpm::util::copy($description_file, "$urpm->{statedir}/descriptions.$medium->{name}")
+ ? $urpm->{log}(N("...copying done"))
+ : do { $urpm->{error}(N("...copying failed")); $medium->{ignore} = 1 };
+ chown 0, 0, "$urpm->{statedir}/descriptions.$medium->{name}";
+ }
+
+ #- examine if a distant MD5SUM file is available.
+ #- this will only be done if $with_hdlist is not empty in order to use
+ #- an existing hdlist or synthesis file, and to check if download was good.
+ #- if no MD5SUM is available, do it as before...
+ #- we can assume at this point a basename is existing, but it needs
+ #- to be checked for being valid, nothing can be deduced if no MD5SUM
+ #- file is present.
+
+ my $error;
+
+ unless ($medium->{virtual}) {
+ if ($medium->{with_hdlist}) {
+ if (!$options->{nomd5sum} && file_size(reduce_pathname("$with_hdlist_dir/../MD5SUM")) > 32) {
+ recompute_local_md5sum($urpm, $medium, $options->{force});
+ if ($medium->{md5sum}) {
+ $$retrieved_md5sum = parse_md5sum($urpm, reduce_pathname("$with_hdlist_dir/../MD5SUM"), basename($with_hdlist_dir));
+ _read_existing_synthesis_and_hdlist_if_same_md5sum($urpm, $medium, $$retrieved_md5sum)
+ and return 'unmodified';
+ }
+ }
- #- check if the files are equal... and no force copy...
- if (!$error && !$options{force} && -e "$urpm->{statedir}/synthesis.$medium->{hdlist}") {
- my @sstat = stat "$urpm->{cachedir}/partial/$medium->{hdlist}";
- my @lstat = stat "$urpm->{statedir}/$medium->{hdlist}";
- if ($sstat[7] == $lstat[7] && $sstat[9] == $lstat[9]) {
- #- the two files are considered equal here, the medium is so not modified.
- $medium->{modified} = 0;
- unlink "$urpm->{cachedir}/partial/$medium->{hdlist}";
- #- as previously done, just read synthesis file here, this is enough, but only
- #- if synthesis exists, else it needs to be recomputed.
- $urpm->{log}(N("examining synthesis file [%s]", "$urpm->{statedir}/synthesis.$medium->{hdlist}"));
- ($medium->{start}, $medium->{end}) =
- $urpm->parse_synthesis("$urpm->{statedir}/synthesis.$medium->{hdlist}");
- unless (defined $medium->{start} && defined $medium->{end}) {
- $urpm->{log}(N("examining hdlist file [%s]", "$urpm->{statedir}/$medium->{hdlist}"));
- ($medium->{start}, $medium->{end}) =
- $urpm->parse_hdlist("$urpm->{statedir}/$medium->{hdlist}", packing => 1);
- unless (defined $medium->{start} && defined $medium->{end}) {
- $urpm->{error}(N("problem reading synthesis file of medium \"%s\"", $medium->{name}));
- $medium->{ignore} = 1;
- }
- }
- next MEDIA;
- }
- }
+ #- if the source hdlist is present and we are not forcing using rpm files
+ if ($options->{force} < 2 && -e $with_hdlist_dir) {
+ unlink cachedir_hdlist($urpm, $medium);
+ $urpm->{log}(N("copying source hdlist (or synthesis) of \"%s\"...", $medium->{name}));
+ $options->{callback} and $options->{callback}('copy', $medium->{name});
+ if (urpm::util::copy($with_hdlist_dir, cachedir_hdlist($urpm, $medium))) {
+ $options->{callback} and $options->{callback}('done', $medium->{name});
+ $urpm->{log}(N("...copying done"));
+ chown 0, 0, cachedir_hdlist($urpm, $medium);
} else {
- if ($urpm->{options}{norebuild}) {
- $urpm->{error}(N("unable to access hdlist file of \"%s\", medium ignored", $medium->{name}));
- $medium->{ignore} = 1;
- } else {
- $options{force} < 2 and $options{force} = 2;
- }
+ $options->{callback} and $options->{callback}('failed', $medium->{name});
+ #- force error, reported afterwards
+ unlink cachedir_hdlist($urpm, $medium);
}
+ }
- #- if copying hdlist has failed, try to build it directly.
- if ($error) {
- if ($urpm->{options}{norebuild}) {
- $urpm->{error}(N("unable to access hdlist file of \"%s\", medium ignored", $medium->{name}));
- $medium->{ignore} = 1;
- } else {
- $options{force} < 2 and $options{force} = 2;
- #- clear error state now.
- $error = undef;
- }
- }
+ file_size(cachedir_hdlist($urpm, $medium)) > 32 or
+ $error = 1, $urpm->{error}(N("copy of [%s] failed (file is suspiciously small)",
+ cachedir_hdlist($urpm, $medium)));
- if ($options{force} < 2) {
- #- examine if a local list file is available (always probed according to with_hdlist)
- #- and check hdlist wasn't named very strangely...
- if ($medium->{hdlist} ne 'list') {
- my $local_list = $medium->{with_hdlist} =~ /hd(list.*)\.cz$/ ? $1 : 'list';
- my $path_list = reduce_pathname("$with_hdlist_dir/../$local_list");
- -e $path_list or $path_list = "$dir/list";
- if (-e $path_list) {
- urpm::util::copy($path_list, "$urpm->{cachedir}/partial/list")
- or do { $urpm->{error}(N("...copying failed")); $error = 1 };
- chown 0, 0, "$urpm->{cachedir}/partial/list";
- }
- }
- } else {
- {
- my %f;
- File::Find::find(
- {
- wanted => sub { -f $_ && /\.rpm$/ and $f{"$File::Find::dir/$_"} = 1 },
- follow_skip => 2,
- follow_fast => 1,
- },
- $dir,
- );
- push @files, keys %f;
- }
+ #- keep checking md5sum of file just copied ! (especially on nfs or removable device).
+ if (!$error && $$retrieved_md5sum) {
+ $urpm->{log}(N("computing md5sum of copied source hdlist (or synthesis)"));
+ md5sum(cachedir_hdlist($urpm, $medium)) eq $$retrieved_md5sum or
+ $error = 1, $urpm->{error}(N("copy of [%s] failed (md5sum mismatch)", $with_hdlist_dir));
+ }
- #- check files contains something good!
- if (@files > 0) {
- #- we need to rebuild from rpm files the hdlist.
- eval {
- $urpm->{log}(N("reading rpm files from [%s]", $dir));
- my @unresolved_before = grep {
- ! defined $urpm->{provides}{$_};
- } keys %{$urpm->{provides} || {}};
- $medium->{start} = @{$urpm->{depslist}};
- $medium->{headers} = [ $urpm->parse_rpms_build_headers(
- dir => "$urpm->{cachedir}/headers",
- rpms => \@files,
- clean => $clean_cache,
- ) ];
- $medium->{end} = $#{$urpm->{depslist}};
- if ($medium->{start} > $medium->{end}) {
- #- an error occured (provided there are files in input.)
- delete $medium->{start};
- delete $medium->{end};
- $urpm->{fatal}(9, N("no rpms read"));
- } else {
- #- make sure the headers will not be removed for another media.
- $clean_cache = 0;
- my @unresolved = grep {
- ! defined $urpm->{provides}{$_};
- } keys %{$urpm->{provides} || {}};
- @unresolved_before == @unresolved or $second_pass = 1;
- }
- };
- $@ and $error = 1, $urpm->{error}(N("unable to read rpm files from [%s]: %s", $dir, $@));
- $error and delete $medium->{headers}; #- do not propagate these.
- $error or delete $medium->{synthesis}; #- when building hdlist by ourself, drop synthesis property.
- } else {
- $error = 1;
- $urpm->{error}(N("no rpm files found from [%s]", $dir));
- $medium->{ignore} = 1;
- }
- }
+ #- check if the files are equal... and no force copy...
+ if (!$error && !$options->{force} && -e statedir_synthesis($urpm, $medium)) {
+ _read_existing_synthesis_and_hdlist_if_same_time_and_msize($urpm, $medium, $medium->{hdlist})
+ and return 'unmodified';
}
+ } else {
+ $error = 1;
+ }
- #- examine if a local pubkey file is available.
- if (!$nopubkey && $medium->{hdlist} ne 'pubkey' && !$medium->{'key-ids'}) {
- my $path_pubkey = reduce_pathname("$with_hdlist_dir/../" . _guess_pubkey_name($medium));
- -e $path_pubkey or $path_pubkey = "$dir/pubkey";
- if ($path_pubkey) {
- urpm::util::copy($path_pubkey, "$urpm->{cachedir}/partial/pubkey")
- or do { $urpm->{error}(N("...copying failed")) };
+ #- if copying hdlist has failed, try to build it directly.
+ if ($error) {
+ if ($urpm->{options}{norebuild}) {
+ $urpm->{error}(N("unable to access hdlist file of \"%s\", medium ignored", $medium->{name}));
+ $medium->{ignore} = 1;
+ } else {
+ $options->{force} < 2 and $options->{force} = 2;
+ #- clear error state now.
+ $error = undef;
+ }
+ }
+
+ if ($options->{force} < 2) {
+ #- examine if a local list file is available (always probed according to with_hdlist)
+ #- and check hdlist wasn't named very strangely...
+ if ($medium->{hdlist} ne 'list') {
+ my $local_list = 'list' . _hdlist_suffix($medium);
+ my $path_list = reduce_pathname("$with_hdlist_dir/../$local_list");
+ -e $path_list or $path_list = "$dir/list";
+ if (-e $path_list) {
+ urpm::util::copy($path_list, "$urpm->{cachedir}/partial/list")
+ or do { $urpm->{error}(N("...copying failed")); $error = 1 };
+ chown 0, 0, "$urpm->{cachedir}/partial/list";
}
- chown 0, 0, "$urpm->{cachedir}/partial/pubkey";
}
} else {
- #- check for a reconfig.urpmi file (if not already reconfigured)
- if (!$media_redone{$medium->{name}} && !$medium->{noreconfigure}) {
- unlink(my $reconfig_urpmi = "$urpm->{cachedir}/partial/reconfig.urpmi");
+ push @$rpm_files, recursive_find_rpm_files($dir);
+
+ #- check files contains something good!
+ if (@$rpm_files > 0) {
+ #- we need to rebuild from rpm files the hdlist.
eval {
- $urpm->{sync}(
- {
- dir => "$urpm->{cachedir}/partial",
- quiet => 1,
- limit_rate => $options{limit_rate},
- compress => $options{compress},
- proxy => get_proxy($medium->{name}),
- media => $medium->{name},
- retry => $urpm->{options}{retry},
- },
- reduce_pathname("$medium->{url}/reconfig.urpmi"),
- );
+ $urpm->{log}(N("reading rpm files from [%s]", $dir));
+ my @unresolved_before = grep {
+ ! defined $urpm->{provides}{$_};
+ } keys %{$urpm->{provides} || {}};
+ $medium->{start} = @{$urpm->{depslist}};
+ $medium->{headers} = [ $urpm->parse_rpms_build_headers(
+ dir => "$urpm->{cachedir}/headers",
+ rpms => $rpm_files,
+ clean => $$clean_cache,
+ ) ];
+ $medium->{end} = $#{$urpm->{depslist}};
+ if ($medium->{start} > $medium->{end}) {
+ #- an error occured (provided there are files in input.)
+ delete $medium->{start};
+ delete $medium->{end};
+ $urpm->{fatal}(9, N("no rpms read"));
+ } else {
+ #- make sure the headers will not be removed for another media.
+ $$clean_cache = 0;
+ my @unresolved = grep {
+ ! defined $urpm->{provides}{$_};
+ } keys %{$urpm->{provides} || {}};
+ @unresolved_before == @unresolved or $$second_pass = 1;
+ }
};
- if (-s $reconfig_urpmi && $urpm->reconfig_urpmi($reconfig_urpmi, $medium->{name})) {
- $media_redone{$medium->{name}} = 1, redo MEDIA unless $media_redone{$medium->{name}};
- }
- unlink $reconfig_urpmi;
+ $@ and $error = 1, $urpm->{error}(N("unable to read rpm files from [%s]: %s", $dir, $@));
+ $error and delete $medium->{headers}; #- do not propagate these.
+ $error or delete $medium->{synthesis}; #- when building hdlist by ourself, drop synthesis property.
+ } else {
+ $error = 1;
+ $urpm->{error}(N("no rpm files found from [%s]", $dir));
+ $medium->{ignore} = 1;
}
+ }
+ }
+
+ #- examine if a local pubkey file is available.
+ if (!$options->{nopubkey} && $medium->{hdlist} ne 'pubkey' && !$medium->{'key-ids'}) {
+ my $path_pubkey = reduce_pathname("$with_hdlist_dir/../pubkey" . _hdlist_suffix($medium));
+ -e $path_pubkey or $path_pubkey = "$dir/pubkey";
+ if ($path_pubkey) {
+ urpm::util::copy($path_pubkey, "$urpm->{cachedir}/partial/pubkey")
+ or do { $urpm->{error}(N("...copying failed")) };
+ }
+ chown 0, 0, "$urpm->{cachedir}/partial/pubkey";
+ }
- my $basename;
+ $error;
+}
- #- try to get the description if it has been found.
- unlink "$urpm->{cachedir}/partial/descriptions";
- if (-e "$urpm->{statedir}/descriptions.$medium->{name}") {
- urpm::util::move("$urpm->{statedir}/descriptions.$medium->{name}", "$urpm->{cachedir}/partial/descriptions");
+sub _read_cachedir_pubkey {
+ my ($urpm, $medium) = @_;
+ -s "$urpm->{cachedir}/partial/pubkey" or return;
+
+ $urpm->{log}(N("examining pubkey file of \"%s\"...", $medium->{name}));
+
+ my %key_ids;
+ $urpm->import_needed_pubkeys(
+ [ $urpm->parse_armored_file("$urpm->{cachedir}/partial/pubkey") ],
+ root => $urpm->{root},
+ callback => sub {
+ my (undef, undef, $_k, $id, $imported) = @_;
+ if ($id) {
+ $key_ids{$id} = undef;
+ $imported and $urpm->{log}(N("...imported key %s from pubkey file of \"%s\"",
+ $id, $medium->{name}));
+ } else {
+ $urpm->{error}(N("unable to import pubkey file of \"%s\"", $medium->{name}));
}
- my $syncopts = {
- dir => "$urpm->{cachedir}/partial",
- quiet => 1,
- limit_rate => $options{limit_rate},
- compress => $options{compress},
- proxy => get_proxy($medium->{name}),
- retry => $urpm->{options}{retry},
- media => $medium->{name},
+ });
+ if (keys(%key_ids)) {
+ $medium->{'key-ids'} = join(',', keys %key_ids);
+ }
+}
+
+sub _update_medium_first_pass {
+ my ($urpm, $medium, $second_pass, $clean_cache, %options) = @_;
+
+ $medium->{ignore} and return;
+
+ $options{forcekey} and delete $medium->{'key-ids'};
+
+ #- we should create the associated synthesis file if it does not already exist...
+ file_size(statedir_synthesis($urpm, $medium)) > 32
+ or $medium->{modified_synthesis} = 1;
+
+ if ($medium->{static}) {
+ #- don't ever update static media
+ $medium->{modified} = 0;
+ } elsif ($options{all}) {
+ #- if we're rebuilding all media, mark them as modified (except removable ones)
+ $medium->{modified} ||= $medium->{url} !~ m!^removable!;
+ }
+
+ unless ($medium->{modified}) {
+ #- the medium is not modified, but to compute dependencies,
+ #- we still need to read it and all synthesis will be written if
+ #- an unresolved provides is found.
+ #- to speed up the process, we only read the synthesis at the beginning.
+ _update_media__when_not_modified($urpm, $medium);
+ return;
+ }
+
+ #- always delete a remaining list file or pubkey file in cache.
+ foreach (qw(list pubkey)) {
+ unlink "$urpm->{cachedir}/partial/$_";
+ }
+
+ #- check for a reconfig.urpmi file (if not already reconfigured)
+ if (!$medium->{noreconfigure}) {
+ may_reconfig_urpmi($urpm, $medium, \%options);
+ }
+
+ #- list of rpm files for this medium, only available for local medium where
+ #- the source hdlist is not used (use force).
+ my ($error, $retrieved_md5sum, @files);
+
+ #- check if the medium is using a local or a removable medium.
+ if (file_from_local_url($medium->{url})) {
+ my $rc = _update_medium_first_pass__local($urpm, $medium, $second_pass, $clean_cache, \$retrieved_md5sum, \@files, \%options);
+ if ($rc eq 'unmodified') {
+ return;
+ } else {
+ $error = $rc;
+ }
+ } else {
+ my $basename;
+
+ #- try to get the description if it has been found.
+ unlink "$urpm->{cachedir}/partial/descriptions";
+ if (-e "$urpm->{statedir}/descriptions.$medium->{name}") {
+ urpm::util::move("$urpm->{statedir}/descriptions.$medium->{name}", "$urpm->{cachedir}/partial/descriptions");
+ }
+ eval {
+ sync_webfetch($urpm, $medium, [ reduce_pathname("$medium->{url}/media_info/descriptions") ],
+ \%options, quiet => 1);
+ };
+ #- It is possible that the original fetch of the descriptions
+ #- failed, but the file still remains in partial/ because it was
+ #- moved from $urpm->{statedir} earlier. So we need to check if
+ #- the previous download failed.
+ if ($@ || ! -e "$urpm->{cachedir}/partial/descriptions") {
+ eval {
+ #- try older location
+ sync_webfetch($urpm, $medium, [ reduce_pathname("$medium->{url}/../descriptions") ],
+ \%options, quiet => 1);
};
- eval { $urpm->{sync}($syncopts, reduce_pathname("$medium->{url}/media_info/descriptions")) };
- #- It is possible that the original fetch of the descriptions
- #- failed, but the file still remains in partial/ because it was
- #- moved from $urpm->{statedir} earlier. So we need to check if
- #- the previous download failed.
- if ($@ || ! -e "$urpm->{cachedir}/partial/descriptions") {
- eval {
- #- try older location
- $urpm->{sync}($syncopts, reduce_pathname("$medium->{url}/../descriptions"));
- };
- }
- if (-e "$urpm->{cachedir}/partial/descriptions") {
- urpm::util::move("$urpm->{cachedir}/partial/descriptions", "$urpm->{statedir}/descriptions.$medium->{name}");
- }
+ }
+ if (-e "$urpm->{cachedir}/partial/descriptions") {
+ urpm::util::move("$urpm->{cachedir}/partial/descriptions", "$urpm->{statedir}/descriptions.$medium->{name}");
+ }
- #- examine if a distant MD5SUM file is available.
- #- this will only be done if $with_hdlist is not empty in order to use
- #- an existing hdlist or synthesis file, and to check if download was good.
- #- if no MD5SUM is available, do it as before...
- if ($medium->{with_hdlist}) {
- #- we can assume at this point a basename is existing, but it needs
- #- to be checked for being valid, nothing can be deduced if no MD5SUM
- #- file is present.
- $basename = basename($medium->{with_hdlist});
+ #- examine if a distant MD5SUM file is available.
+ #- this will only be done if $with_hdlist is not empty in order to use
+ #- an existing hdlist or synthesis file, and to check if download was good.
+ #- if no MD5SUM is available, do it as before...
+ if ($medium->{with_hdlist}) {
+ #- we can assume at this point a basename is existing, but it needs
+ #- to be checked for being valid, nothing can be deduced if no MD5SUM
+ #- file is present.
+ $basename = basename($medium->{with_hdlist});
- unlink "$urpm->{cachedir}/partial/MD5SUM";
- eval {
- if (!$options{nomd5sum}) {
- $urpm->{sync}(
- {
- dir => "$urpm->{cachedir}/partial",
- quiet => 1,
- limit_rate => $options{limit_rate},
- compress => $options{compress},
- proxy => get_proxy($medium->{name}),
- media => $medium->{name},
- retry => $urpm->{options}{retry},
- },
- reduce_pathname("$medium->{url}/$medium->{with_hdlist}/../MD5SUM"),
- );
- }
- };
- if (!$@ && file_size("$urpm->{cachedir}/partial/MD5SUM") > 32) {
- recompute_local_md5sum($urpm, $medium, $options{force} >= 2);
- if ($medium->{md5sum}) {
- $retrieved_md5sum = parse_md5sum($urpm, "$urpm->{cachedir}/partial/MD5SUM", $basename);
- #- if an existing hdlist or synthesis file has the same md5sum, we assume the
- #- files are the same.
- #- if local md5sum is the same as distant md5sum, this means there is no need to
- #- download hdlist or synthesis file again.
- if (defined $retrieved_md5sum && $medium->{md5sum} eq $retrieved_md5sum) {
- unlink "$urpm->{cachedir}/partial/$basename";
- #- the medium is now considered not modified.
- $medium->{modified} = 0;
- #- XXX we could link the new hdlist to the old one.
- #- (However links need to be managed. see bug #12391.)
- #- as previously done, just read synthesis file here, this is enough.
- $urpm->{log}(N("examining synthesis file [%s]", "$urpm->{statedir}/synthesis.$medium->{hdlist}"));
- ($medium->{start}, $medium->{end}) =
- $urpm->parse_synthesis("$urpm->{statedir}/synthesis.$medium->{hdlist}");
- unless (defined $medium->{start} && defined $medium->{end}) {
- $urpm->{log}(N("examining hdlist file [%s]", "$urpm->{statedir}/$medium->{hdlist}"));
- ($medium->{start}, $medium->{end}) =
- $urpm->parse_hdlist("$urpm->{statedir}/$medium->{hdlist}", packing => 1);
- unless (defined $medium->{start} && defined $medium->{end}) {
- $urpm->{error}(N("problem reading synthesis file of medium \"%s\"", $medium->{name}));
- $medium->{ignore} = 1;
- }
- }
- }
- $medium->{modified} or next MEDIA;
- }
- } else {
- #- at this point, we don't if a basename exists and is valid, let probe it later.
- $basename = undef;
+ unlink "$urpm->{cachedir}/partial/MD5SUM";
+ eval {
+ if (!$options{nomd5sum}) {
+ sync_webfetch($urpm, $medium,
+ [ reduce_pathname("$medium->{url}/$medium->{with_hdlist}/../MD5SUM") ],
+ \%options, quiet => 1);
}
- }
-
- #- try to probe for possible with_hdlist parameter, unless
- #- it is already defined (and valid).
- $urpm->{log}(N("retrieving source hdlist (or synthesis) of \"%s\"...", $medium->{name}));
- $options{callback} and $options{callback}('retrieve', $medium->{name});
- if ($options{probe_with}) {
- my @probe_list = (
- $medium->{with_hdlist}
- ? $medium->{with_hdlist}
- : _probe_with_try_list(_guess_hdlist_suffix($dir), $options{probe_with})
- );
- foreach my $with_hdlist (@probe_list) {
- $basename = basename($with_hdlist) or next;
- $options{force} and unlink "$urpm->{cachedir}/partial/$basename";
- eval {
- $urpm->{sync}(
- {
- dir => "$urpm->{cachedir}/partial",
- quiet => $options{quiet},
- limit_rate => $options{limit_rate},
- compress => $options{compress},
- callback => $options{callback},
- proxy => get_proxy($medium->{name}),
- media => $medium->{name},
- retry => $urpm->{options}{retry},
- },
- reduce_pathname("$medium->{url}/$with_hdlist"),
- );
- };
- if (!$@ && file_size("$urpm->{cachedir}/partial/$basename") > 32) {
- $medium->{with_hdlist} = $with_hdlist;
- $urpm->{log}(N("found probed hdlist (or synthesis) as %s", $medium->{with_hdlist}));
- last; #- found a suitable with_hdlist in the list above.
- }
+ };
+ if (!$@ && file_size("$urpm->{cachedir}/partial/MD5SUM") > 32) {
+ recompute_local_md5sum($urpm, $medium, $options{force} >= 2);
+ if ($medium->{md5sum}) {
+ $retrieved_md5sum = parse_md5sum($urpm, "$urpm->{cachedir}/partial/MD5SUM", $basename);
+ _read_existing_synthesis_and_hdlist_if_same_md5sum($urpm, $medium, $retrieved_md5sum)
+ and return;
}
} else {
- $basename = basename($medium->{with_hdlist});
+ #- at this point, we don't if a basename exists and is valid, let probe it later.
+ $basename = undef;
+ }
+ }
- #- try to sync (copy if needed) local copy after restored the previous one.
+ #- try to probe for possible with_hdlist parameter, unless
+ #- it is already defined (and valid).
+ $urpm->{log}(N("retrieving source hdlist (or synthesis) of \"%s\"...", $medium->{name}));
+ $options{callback} and $options{callback}('retrieve', $medium->{name});
+ if ($options{probe_with}) {
+ my @probe_list = (
+ $medium->{with_hdlist}
+ ? $medium->{with_hdlist}
+ : _probe_with_try_list(_guess_hdlist_suffix($medium->{url}), $options{probe_with})
+ );
+ foreach my $with_hdlist (@probe_list) {
+ $basename = basename($with_hdlist) or next;
$options{force} and unlink "$urpm->{cachedir}/partial/$basename";
- unless ($options{force}) {
- if ($medium->{synthesis}) {
- if (-e "$urpm->{statedir}/synthesis.$medium->{hdlist}") {
- urpm::util::copy(
- "$urpm->{statedir}/synthesis.$medium->{hdlist}",
- "$urpm->{cachedir}/partial/$basename",
- ) or $urpm->{error}(N("...copying failed")), $error = 1;
- }
- } else {
- if (-e "$urpm->{statedir}/$medium->{hdlist}") {
- urpm::util::copy(
- "$urpm->{statedir}/$medium->{hdlist}",
- "$urpm->{cachedir}/partial/$basename",
- ) or $urpm->{error}(N("...copying failed")), $error = 1;
- }
- }
- chown 0, 0, "$urpm->{cachedir}/partial/$basename";
- }
eval {
- $urpm->{sync}(
- {
- dir => "$urpm->{cachedir}/partial",
- quiet => $options{quiet},
- limit_rate => $options{limit_rate},
- compress => $options{compress},
- callback => $options{callback},
- proxy => get_proxy($medium->{name}),
- media => $medium->{name},
- retry => $urpm->{options}{retry},
- },
- reduce_pathname("$medium->{url}/$medium->{with_hdlist}"),
- );
+ sync_webfetch($urpm, $medium, [ reduce_pathname("$medium->{url}/$with_hdlist") ],
+ \%options, callback => $options{callback});
};
- if ($@) {
- $urpm->{error}(N("...retrieving failed: %s", $@));
- unlink "$urpm->{cachedir}/partial/$basename";
+ if (!$@ && file_size("$urpm->{cachedir}/partial/$basename") > 32) {
+ $medium->{with_hdlist} = $with_hdlist;
+ $urpm->{log}(N("found probed hdlist (or synthesis) as %s", $medium->{with_hdlist}));
+ last; #- found a suitable with_hdlist in the list above.
}
}
+ } else {
+ $basename = basename($medium->{with_hdlist});
- #- check downloaded file has right signature.
- if (file_size("$urpm->{cachedir}/partial/$basename") > 32 && $retrieved_md5sum) {
- $urpm->{log}(N("computing md5sum of retrieved source hdlist (or synthesis)"));
- unless (md5sum("$urpm->{cachedir}/partial/$basename") eq $retrieved_md5sum) {
- $urpm->{error}(N("...retrieving failed: md5sum mismatch"));
- unlink "$urpm->{cachedir}/partial/$basename";
+ if ($options{force}) {
+ unlink "$urpm->{cachedir}/partial/$basename";
+ } else {
+ #- try to sync (copy if needed) local copy after restored the previous one.
+ #- this is useful for rsync (?)
+ if (-e statedir_hdlist_or_synthesis($urpm, $medium)) {
+ urpm::util::copy(
+ statedir_hdlist_or_synthesis($urpm, $medium),
+ "$urpm->{cachedir}/partial/$basename",
+ ) or $urpm->{error}(N("...copying failed")), $error = 1;
}
+ chown 0, 0, "$urpm->{cachedir}/partial/$basename";
+ }
+ eval {
+ sync_webfetch($urpm, $medium, [ reduce_pathname("$medium->{url}/$medium->{with_hdlist}") ],
+ \%options, callback => $options{callback});
+ };
+ if ($@) {
+ $urpm->{error}(N("...retrieving failed: %s", $@));
+ unlink "$urpm->{cachedir}/partial/$basename";
}
+ }
- if (file_size("$urpm->{cachedir}/partial/$basename") > 32) {
- $options{callback} and $options{callback}('done', $medium->{name});
- $urpm->{log}(N("...retrieving done"));
+ #- check downloaded file has right signature.
+ if (file_size("$urpm->{cachedir}/partial/$basename") > 32 && $retrieved_md5sum) {
+ $urpm->{log}(N("computing md5sum of retrieved source hdlist (or synthesis)"));
+ unless (md5sum("$urpm->{cachedir}/partial/$basename") eq $retrieved_md5sum) {
+ $urpm->{error}(N("...retrieving failed: md5sum mismatch"));
+ unlink "$urpm->{cachedir}/partial/$basename";
+ }
+ }
- unless ($options{force}) {
- my @sstat = stat "$urpm->{cachedir}/partial/$basename";
- my @lstat = stat "$urpm->{statedir}/$medium->{hdlist}";
- if ($sstat[7] == $lstat[7] && $sstat[9] == $lstat[9]) {
- #- the two files are considered equal here, the medium is so not modified.
- $medium->{modified} = 0;
- unlink "$urpm->{cachedir}/partial/$basename";
- #- as previously done, just read synthesis file here, this is enough.
- $urpm->{log}(N("examining synthesis file [%s]", "$urpm->{statedir}/synthesis.$medium->{hdlist}"));
- ($medium->{start}, $medium->{end}) =
- $urpm->parse_synthesis("$urpm->{statedir}/synthesis.$medium->{hdlist}");
- unless (defined $medium->{start} && defined $medium->{end}) {
- $urpm->{log}(N("examining hdlist file [%s]", "$urpm->{statedir}/$medium->{hdlist}"));
- ($medium->{start}, $medium->{end}) =
- $urpm->parse_hdlist("$urpm->{statedir}/$medium->{hdlist}", packing => 1);
- unless (defined $medium->{start} && defined $medium->{end}) {
- $urpm->{error}(N("problem reading hdlist or synthesis file of medium \"%s\"", $medium->{name}));
- $medium->{ignore} = 1;
- }
- }
- next MEDIA;
- }
- }
+ if (file_size("$urpm->{cachedir}/partial/$basename") > 32) {
+ $options{callback} and $options{callback}('done', $medium->{name});
+ $urpm->{log}(N("...retrieving done"));
- #- the files are different, update local copy.
- rename("$urpm->{cachedir}/partial/$basename", "$urpm->{cachedir}/partial/$medium->{hdlist}");
-
- #- retrieval of hdlist or synthesis has been successful,
- #- check whether a list file is available.
- #- and check hdlist wasn't named very strangely...
- if ($medium->{hdlist} ne 'list') {
- my $local_list = $medium->{with_hdlist} =~ /hd(list.*)\.cz$/ ? $1 : 'list';
- foreach (reduce_pathname("$medium->{url}/$medium->{with_hdlist}/../$local_list"),
- reduce_pathname("$medium->{url}/list"),
- ) {
- eval {
- $urpm->{sync}(
- {
- dir => "$urpm->{cachedir}/partial",
- quiet => 1,
- limit_rate => $options{limit_rate},
- compress => $options{compress},
- proxy => get_proxy($medium->{name}),
- media => $medium->{name},
- retry => $urpm->{options}{retry},
- },
- $_
- );
- $local_list ne 'list' && -s "$urpm->{cachedir}/partial/$local_list"
- and rename(
- "$urpm->{cachedir}/partial/$local_list",
- "$urpm->{cachedir}/partial/list");
- };
- $@ and unlink "$urpm->{cachedir}/partial/list";
- -s "$urpm->{cachedir}/partial/list" and last;
- }
- }
+ unless ($options{force}) {
+ _read_existing_synthesis_and_hdlist_if_same_time_and_msize($urpm, $medium, $basename)
+ and return;
+ }
- #- retrieve pubkey file.
- if (!$nopubkey && $medium->{hdlist} ne 'pubkey' && !$medium->{'key-ids'}) {
- my $local_pubkey = _guess_pubkey_name($medium);
- foreach (reduce_pathname("$medium->{url}/$medium->{with_hdlist}/../$local_pubkey"),
- reduce_pathname("$medium->{url}/pubkey"),
- ) {
- eval {
- $urpm->{sync}(
- {
- dir => "$urpm->{cachedir}/partial",
- quiet => 1,
- limit_rate => $options{limit_rate},
- compress => $options{compress},
- proxy => get_proxy($medium->{name}),
- media => $medium->{name},
- retry => $urpm->{options}{retry},
- },
- $_,
- );
- $local_pubkey ne 'pubkey' && -s "$urpm->{cachedir}/partial/$local_pubkey"
- and rename(
- "$urpm->{cachedir}/partial/$local_pubkey",
- "$urpm->{cachedir}/partial/pubkey");
- };
- $@ and unlink "$urpm->{cachedir}/partial/pubkey";
- -s "$urpm->{cachedir}/partial/pubkey" and last;
- }
- }
- } else {
- $error = 1;
- $options{callback} and $options{callback}('failed', $medium->{name});
- $urpm->{error}(N("retrieval of source hdlist (or synthesis) failed"));
+ #- the files are different, update local copy.
+ rename("$urpm->{cachedir}/partial/$basename", cachedir_hdlist($urpm, $medium));
+
+ #- retrieval of hdlist or synthesis has been successful,
+ #- check whether a list file is available.
+ #- and check hdlist wasn't named very strangely...
+ if ($medium->{hdlist} ne 'list') {
+ _update_media__sync_file($urpm, $medium, 'list', \%options);
}
- }
- #- build list file according to hdlist.
- unless ($medium->{headers} || file_size("$urpm->{cachedir}/partial/$medium->{hdlist}") > 32) {
+ #- retrieve pubkey file.
+ if (!$options{nopubkey} && $medium->{hdlist} ne 'pubkey' && !$medium->{'key-ids'}) {
+ _update_media__sync_file($urpm, $medium, 'pubkey', \%options);
+ }
+ } else {
$error = 1;
- $urpm->{error}(N("no hdlist file found for medium \"%s\"", $medium->{name}));
- }
-
- unless ($error || $medium->{virtual}) {
- #- sort list file contents according to id.
- my %list;
- if ($medium->{headers}) {
- #- rpm files have already been read (first pass), there is just a need to
- #- build list hash.
- foreach (@files) {
- m|/([^/]*\.rpm)$| or next;
- $list{$1} and $urpm->{error}(N("file [%s] already used in the same medium \"%s\"", $1, $medium->{name})), next;
- $list{$1} = "$prefix:/$_\n";
- }
- } else {
- #- read first pass hdlist or synthesis, try to open as synthesis, if file
- #- is larger than 1MB, this is probably an hdlist else a synthesis.
- #- anyway, if one tries fails, try another mode.
- $options{callback} and $options{callback}('parse', $medium->{name});
- my @unresolved_before = grep { ! defined $urpm->{provides}{$_} } keys %{$urpm->{provides} || {}};
- if (!$medium->{synthesis}
- || file_size("$urpm->{cachedir}/partial/$medium->{hdlist}") > 262144)
- {
- $urpm->{log}(N("examining hdlist file [%s]", "$urpm->{cachedir}/partial/$medium->{hdlist}"));
- ($medium->{start}, $medium->{end}) =
- $urpm->parse_hdlist("$urpm->{cachedir}/partial/$medium->{hdlist}", 1);
- if (defined $medium->{start} && defined $medium->{end}) {
- delete $medium->{synthesis};
- } else {
- $urpm->{log}(N("examining synthesis file [%s]", "$urpm->{cachedir}/partial/$medium->{hdlist}"));
- ($medium->{start}, $medium->{end}) =
- $urpm->parse_synthesis("$urpm->{cachedir}/partial/$medium->{hdlist}");
- defined $medium->{start} && defined $medium->{end} and $medium->{synthesis} = 1;
- }
+ $options{callback} and $options{callback}('failed', $medium->{name});
+ $urpm->{error}(N("retrieval of source hdlist (or synthesis) failed"));
+ }
+ }
+
+ #- build list file according to hdlist.
+ unless ($medium->{headers} || file_size(cachedir_hdlist($urpm, $medium)) > 32) {
+ $error = 1;
+ $urpm->{error}(N("no hdlist file found for medium \"%s\"", $medium->{name}));
+ }
+
+ unless ($error || $medium->{virtual}) {
+ #- sort list file contents according to id.
+ my %list;
+ if ($medium->{headers}) {
+ my $protocol = protocol_from_url($medium->{url});
+
+ #- rpm files have already been read (first pass), there is just a need to
+ #- build list hash.
+ foreach (@files) {
+ m|/([^/]*\.rpm)$| or next;
+ $list{$1} and $urpm->{error}(N("file [%s] already used in the same medium \"%s\"", $1, $medium->{name})), next;
+ $list{$1} = "$protocol:/$_\n";
+ }
+ } else {
+ #- read first pass hdlist or synthesis, try to open as synthesis, if file
+ #- is larger than 1MB, this is probably an hdlist else a synthesis.
+ #- anyway, if one tries fails, try another mode.
+ $options{callback} and $options{callback}('parse', $medium->{name});
+ my @unresolved_before = grep { ! defined $urpm->{provides}{$_} } keys %{$urpm->{provides} || {}};
+ if (!$medium->{synthesis}
+ || file_size(cachedir_hdlist($urpm, $medium)) > 262144) {
+ _parse_hdlist($urpm, $medium, cachedir_hdlist($urpm, $medium));
+ if (is_valid_medium($medium)) {
+ delete $medium->{synthesis};
} else {
- $urpm->{log}(N("examining synthesis file [%s]", "$urpm->{cachedir}/partial/$medium->{hdlist}"));
- ($medium->{start}, $medium->{end}) =
- $urpm->parse_synthesis("$urpm->{cachedir}/partial/$medium->{hdlist}");
- if (defined $medium->{start} && defined $medium->{end}) {
- $medium->{synthesis} = 1;
- } else {
- $urpm->{log}(N("examining hdlist file [%s]", "$urpm->{cachedir}/partial/$medium->{hdlist}"));
- ($medium->{start}, $medium->{end}) =
- $urpm->parse_hdlist("$urpm->{cachedir}/partial/$medium->{hdlist}", 1);
- defined $medium->{start} && defined $medium->{end} and delete $medium->{synthesis};
- }
+ _parse_synthesis($urpm, $medium, cachedir_hdlist($urpm, $medium));
+ is_valid_medium($medium) and $medium->{synthesis} = 1;
}
- if (defined $medium->{start} && defined $medium->{end}) {
- $options{callback} && $options{callback}('done', $medium->{name});
+ } else {
+ _parse_synthesis($urpm, $medium, cachedir_hdlist($urpm, $medium));
+ if (is_valid_medium($medium)) {
+ $medium->{synthesis} = 1;
} else {
- $error = 1;
- $urpm->{error}(N("unable to parse hdlist file of \"%s\"", $medium->{name}));
- $options{callback} && $options{callback}('failed', $medium->{name});
- #- we will have to read back the current synthesis file unmodified.
- }
-
- unless ($error) {
- my @unresolved_after = grep { ! defined $urpm->{provides}{$_} } keys %{$urpm->{provides} || {}};
- @unresolved_before == @unresolved_after or $second_pass = 1;
-
- if ($medium->{hdlist} ne 'list' && -s "$urpm->{cachedir}/partial/list") {
- if (open my $fh, "$urpm->{cachedir}/partial/list") {
- local $_;
- while (<$fh>) {
- m|/([^/]*\.rpm)$| or next;
- $list{$1} and $urpm->{error}(N("file [%s] already used in the same medium \"%s\"", $1, $medium->{name})), next;
- $list{$1} = "$medium->{url}/$_";
- }
- close $fh;
- }
- } else {
- #- if url is clear and no relative list file has been downloaded,
- #- there is no need for a list file.
- if ($medium->{url} ne $medium->{clear_url}) {
- foreach ($medium->{start} .. $medium->{end}) {
- my $filename = $urpm->{depslist}[$_]->filename;
- $list{$filename} = "$medium->{url}/$filename\n";
- }
- }
- }
+ _parse_hdlist($urpm, $medium, cachedir_hdlist($urpm, $medium));
+ is_valid_medium($medium) and delete $medium->{synthesis};
}
}
+ if (is_valid_medium($medium)) {
+ $options{callback} && $options{callback}('done', $medium->{name});
+ } else {
+ $error = 1;
+ $urpm->{error}(N("unable to parse hdlist file of \"%s\"", $medium->{name}));
+ $options{callback} && $options{callback}('failed', $medium->{name});
+ #- we will have to read back the current synthesis file unmodified.
+ }
unless ($error) {
- if (keys %list) {
- #- write list file.
- #- make sure group and other do not have any access to this file, used to hide passwords.
- if ($medium->{list}) {
- my $mask = umask 077;
- open my $listfh, ">", "$urpm->{cachedir}/partial/$medium->{list}"
- or $error = 1, $urpm->{error}(N("unable to write list file of \"%s\"", $medium->{name}));
- umask $mask;
- print $listfh values %list;
- close $listfh;
- }
-
- #- check if at least something has been written into list file.
- if ($medium->{list} && -s "$urpm->{cachedir}/partial/$medium->{list}") {
- $urpm->{log}(N("writing list file for medium \"%s\"", $medium->{name}));
- } else {
- $error = 1, $urpm->{error}(N("nothing written in list file for \"%s\"", $medium->{name}));
+ my @unresolved_after = grep { ! defined $urpm->{provides}{$_} } keys %{$urpm->{provides} || {}};
+ @unresolved_before == @unresolved_after or $$second_pass = 1;
+
+ if ($medium->{hdlist} ne 'list' && -s "$urpm->{cachedir}/partial/list") {
+ if (open my $fh, "$urpm->{cachedir}/partial/list") {
+ local $_;
+ while (<$fh>) {
+ m|/([^/]*\.rpm)$| or next;
+ $list{$1} and $urpm->{error}(N("file [%s] already used in the same medium \"%s\"", $1, $medium->{name})), next;
+ $list{$1} = "$medium->{url}/$_";
+ }
+ close $fh;
}
} else {
- #- the flag is no longer necessary.
- if ($medium->{list}) {
- unlink "$urpm->{statedir}/$medium->{list}";
- delete $medium->{list};
+ #- if url is clear and no relative list file has been downloaded,
+ #- there is no need for a list file.
+ if ($medium->{url} ne $medium->{clear_url}) {
+ foreach ($medium->{start} .. $medium->{end}) {
+ my $filename = $urpm->{depslist}[$_]->filename;
+ $list{$filename} = "$medium->{url}/$filename\n";
+ }
}
}
}
}
unless ($error) {
- #- now... on pubkey
- if (-s "$urpm->{cachedir}/partial/pubkey") {
- $urpm->{log}(N("examining pubkey file of \"%s\"...", $medium->{name}));
- my %key_ids;
- $urpm->import_needed_pubkeys([ $urpm->parse_armored_file("$urpm->{cachedir}/partial/pubkey") ],
- root => $urpm->{root}, callback => sub {
- my (undef, undef, $_k, $id, $imported) = @_;
- if ($id) {
- $key_ids{$id} = undef;
- $imported and $urpm->{log}(N("...imported key %s from pubkey file of \"%s\"",
- $id, $medium->{name}));
- } else {
- $urpm->{error}(N("unable to import pubkey file of \"%s\"", $medium->{name}));
- }
- });
- keys(%key_ids) and $medium->{'key-ids'} = join ',', keys %key_ids;
- }
- }
-
- unless ($medium->{virtual}) {
- if ($error) {
- #- an error has occured for updating the medium, we have to remove temporary files.
- unlink "$urpm->{cachedir}/partial/$medium->{hdlist}";
- $medium->{list} and unlink "$urpm->{cachedir}/partial/$medium->{list}";
- #- read default synthesis (we have to make sure nothing get out of depslist).
- $urpm->{log}(N("examining synthesis file [%s]", "$urpm->{statedir}/synthesis.$medium->{hdlist}"));
- ($medium->{start}, $medium->{end}) = $urpm->parse_synthesis("$urpm->{statedir}/synthesis.$medium->{hdlist}");
- unless (defined $medium->{start} && defined $medium->{end}) {
- $urpm->{error}(N("problem reading synthesis file of medium \"%s\"", $medium->{name}));
- $medium->{ignore} = 1;
+ if (keys %list) {
+ #- write list file.
+ #- make sure group and other do not have any access to this file, used to hide passwords.
+ if ($medium->{list}) {
+ my $mask = umask 077;
+ open my $listfh, ">", cachedir_list($urpm, $medium)
+ or $error = 1, $urpm->{error}(N("unable to write list file of \"%s\"", $medium->{name}));
+ umask $mask;
+ print $listfh values %list;
+ close $listfh;
}
- } else {
- #- make sure to rebuild base files and clear medium modified state.
- $medium->{modified} = 0;
- $urpm->{modified} = 1;
-
- #- but use newly created file.
- unlink "$urpm->{statedir}/$medium->{hdlist}";
- $medium->{synthesis} and unlink "$urpm->{statedir}/synthesis.$medium->{hdlist}";
- $medium->{list} and unlink "$urpm->{statedir}/$medium->{list}";
- unless ($medium->{headers}) {
- unlink "$urpm->{statedir}/synthesis.$medium->{hdlist}";
- unlink "$urpm->{statedir}/$medium->{hdlist}";
- urpm::util::move("$urpm->{cachedir}/partial/$medium->{hdlist}",
- $medium->{synthesis}
- ? "$urpm->{statedir}/synthesis.$medium->{hdlist}"
- : "$urpm->{statedir}/$medium->{hdlist}"
- );
+
+ #- check if at least something has been written into list file.
+ if ($medium->{list} && -s cachedir_list($urpm, $medium)) {
+ $urpm->{log}(N("writing list file for medium \"%s\"", $medium->{name}));
+ } else {
+ $error = 1, $urpm->{error}(N("nothing written in list file for \"%s\"", $medium->{name}));
}
+ } else {
+ #- the flag is no longer necessary.
if ($medium->{list}) {
- urpm::util::move("$urpm->{cachedir}/partial/$medium->{list}", "$urpm->{statedir}/$medium->{list}");
+ unlink statedir_list($urpm, $medium);
+ delete $medium->{list};
}
- $medium->{md5sum} = $retrieved_md5sum; #- anyway, keep it, the previous one is no longer useful.
+ }
+ }
+ }
+
+ unless ($error) {
+ #- now... on pubkey
+ _read_cachedir_pubkey($urpm, $medium);
+ }
+
+ unless ($medium->{virtual}) {
+ if ($error) {
+ #- an error has occured for updating the medium, we have to remove temporary files.
+ unlink cachedir_hdlist($urpm, $medium);
+ $medium->{list} and unlink cachedir_list($urpm, $medium);
+ #- read default synthesis (we have to make sure nothing get out of depslist).
+ _parse_synthesis($urpm, $medium, statedir_synthesis($urpm, $medium));
+ if (!is_valid_medium($medium)) {
+ $urpm->{error}(N("problem reading synthesis file of medium \"%s\"", $medium->{name}));
+ $medium->{ignore} = 1;
+ }
+ } else {
+ #- make sure to rebuild base files and clear medium modified state.
+ $medium->{modified} = 0;
+ $urpm->{md5sum_modified} = 1;
+
+ #- but use newly created file.
+ unlink statedir_hdlist($urpm, $medium);
+ $medium->{synthesis} and unlink statedir_synthesis($urpm, $medium);
+ $medium->{list} and unlink statedir_list($urpm, $medium);
+ unless ($medium->{headers}) {
+ unlink statedir_synthesis($urpm, $medium);
+ unlink statedir_hdlist($urpm, $medium);
+ urpm::util::move(cachedir_hdlist($urpm, $medium),
+ statedir_hdlist_or_synthesis($urpm, $medium));
+ }
+ if ($medium->{list}) {
+ urpm::util::move(cachedir_list($urpm, $medium), statedir_list($urpm, $medium));
+ }
+ $medium->{md5sum} = $retrieved_md5sum; #- anyway, keep it, the previous one is no longer useful.
- #- and create synthesis file associated.
- $medium->{modified_synthesis} = !$medium->{synthesis};
+ #- and create synthesis file associated.
+ $medium->{modified_synthesis} = !$medium->{synthesis};
+ }
+ }
+}
+
+#- take care of modified medium only, or all if all have to be recomputed.
+sub _update_medium_second_pass {
+ my ($urpm, $medium, $second_pass, $callback) = @_;
+
+ $medium->{ignore} and return;
+
+ $callback and $callback->('parse', $medium->{name});
+ #- a modified medium is an invalid medium, we have to read back the previous hdlist
+ #- or synthesis which has not been modified by first pass above.
+ if ($medium->{headers} && !$medium->{modified}) {
+ if ($second_pass) {
+ $urpm->{log}(N("reading headers from medium \"%s\"", $medium->{name}));
+ ($medium->{start}, $medium->{end}) = $urpm->parse_headers(dir => "$urpm->{cachedir}/headers",
+ headers => $medium->{headers},
+ );
+ }
+ $urpm->{log}(N("building hdlist [%s]", statedir_hdlist($urpm, $medium)));
+ #- finish building operation of hdlist.
+ $urpm->build_hdlist(start => $medium->{start},
+ end => $medium->{end},
+ dir => "$urpm->{cachedir}/headers",
+ hdlist => statedir_hdlist($urpm, $medium),
+ );
+ #- synthesis needs to be created, since the medium has been built from rpm files.
+ eval { $urpm->build_synthesis(
+ start => $medium->{start},
+ end => $medium->{end},
+ synthesis => statedir_synthesis($urpm, $medium),
+ ) };
+ if ($@) {
+ #- XXX this happens when building a synthesis for a local media from RPMs... why ?
+ $urpm->{error}(N("Unable to build synthesis file for medium \"%s\". Your hdlist file may be corrupted.", $medium->{name}));
+ $urpm->{error}($@);
+ unlink statedir_synthesis($urpm, $medium);
+ } else {
+ $urpm->{log}(N("built hdlist synthesis file for medium \"%s\"", $medium->{name}));
+ }
+ #- keep in mind we have a modified database, sure at this point.
+ $urpm->{md5sum_modified} = 1;
+ } elsif ($medium->{synthesis}) {
+ if ($second_pass) {
+ if ($medium->{virtual}) {
+ if (file_from_file_url($medium->{url})) {
+ _parse_synthesis($urpm, $medium, hdlist_or_synthesis_for_virtual_medium($medium));
+ }
+ } else {
+ _parse_synthesis($urpm, $medium, statedir_synthesis($urpm, $medium));
+ }
+ }
+ } else {
+ if ($second_pass) {
+ _parse_hdlist($urpm, $medium, statedir_hdlist($urpm, $medium));
+ }
+ #- check if the synthesis file can be built.
+ if (($second_pass || $medium->{modified_synthesis}) && !$medium->{modified}) {
+ unless ($medium->{virtual}) {
+ eval { $urpm->build_synthesis(
+ start => $medium->{start},
+ end => $medium->{end},
+ synthesis => statedir_synthesis($urpm, $medium),
+ ) };
+ if ($@) {
+ $urpm->{error}(N("Unable to build synthesis file for medium \"%s\". Your hdlist file may be corrupted.", $medium->{name}));
+ $urpm->{error}($@);
+ unlink statedir_synthesis($urpm, $medium);
+ } else {
+ $urpm->{log}(N("built hdlist synthesis file for medium \"%s\"", $medium->{name}));
+ }
}
+ #- keep in mind we have modified database, sure at this point.
+ $urpm->{md5sum_modified} = 1;
+ }
+ }
+ $callback && $callback->('done', $medium->{name});
+}
+
+sub remove_obsolete_headers_in_cache {
+ my ($urpm) = @_;
+ my %headers;
+ my $dh = $urpm->opendir_safe("$urpm->{cachedir}/headers");
+ if ($dh) {
+ local $_;
+ while (defined($_ = readdir $dh)) {
+ m|^([^/]*-[^-]*-[^-]*\.[^\.]*)(?::\S*)?$| and $headers{$1} = $_;
}
+ closedir $dh;
+ }
+ if (%headers) {
+ $urpm->{log}(N("found %d headers in cache", scalar(keys %headers)));
+ foreach (@{$urpm->{depslist}}) {
+ delete $headers{$_->fullname};
+ }
+ $urpm->{log}(N("removing %d obsolete headers in cache", scalar(keys %headers)));
+ foreach (values %headers) {
+ unlink "$urpm->{cachedir}/headers/$_";
+ }
+ }
+}
+
+#- Update the urpmi database w.r.t. the current configuration.
+#- Takes care of modifications, and tries some tricks to bypass
+#- the recomputation of base files.
+#- Recognized options :
+#- all : all medias are being rebuilt
+#- callback : UI callback
+#- compress : use compressed download (for rsync)
+#- forcekey : force retrieval of pubkey
+#- force : try to force rebuilding base files (1) or hdlist from rpm files (2)
+#- limit_rate : download limit rate
+#- noclean : keep old files in the header cache directory
+#- nolock : don't lock the urpmi database
+#- nomd5sum : don't verify MD5SUM of retrieved files
+#- nopubkey : don't use rpm pubkeys
+#- norebuild : don't try to rebuild hdlists from rpm headers
+#- probe_with : probe synthesis or hdlist (or none)
+#- quiet : download hdlists quietly
+#- ratio : use this compression ratio (with gzip, default is 4)
+sub update_media {
+ my ($urpm, %options) = @_;
+
+ $urpm->{media} or return; # verify that configuration has been read
+
+ $options{nopubkey} ||= $urpm->{options}{nopubkey};
+ #- get gpg-pubkey signature.
+ if (!$options{nopubkey}) {
+ $urpm->lock_rpm_db('exclusive');
+ $urpm->{keys} or $urpm->parse_pubkeys(root => $urpm->{root});
+ }
+ #- lock database if allowed.
+ $urpm->lock_urpmi_db('exclusive') if !$options{nolock};
+
+ #- examine each medium to see if one of them needs to be updated.
+ #- if this is the case and if not forced, try to use a pre-calculated
+ #- hdlist file, else build it from rpm files.
+ $urpm->clean;
+
+ my $clean_cache = !$options{noclean};
+ my $second_pass;
+ foreach my $medium (@{$urpm->{media}}) {
+ _update_medium_first_pass($urpm, $medium, \$second_pass, \$clean_cache, %options);
}
#- some unresolved provides may force to rebuild all synthesis,
@@ -1922,116 +2019,27 @@ this could happen if you mounted manually the directory when creating the medium
#- second pass consists in reading again synthesis or hdlists.
foreach my $medium (@{$urpm->{media}}) {
- #- take care of modified medium only, or all if all have to be recomputed.
- $medium->{ignore} and next;
-
- $options{callback} and $options{callback}('parse', $medium->{name});
- #- a modified medium is an invalid medium, we have to read back the previous hdlist
- #- or synthesis which has not been modified by first pass above.
- if ($medium->{headers} && !$medium->{modified}) {
- if ($second_pass) {
- $urpm->{log}(N("reading headers from medium \"%s\"", $medium->{name}));
- ($medium->{start}, $medium->{end}) = $urpm->parse_headers(dir => "$urpm->{cachedir}/headers",
- headers => $medium->{headers},
- );
- }
- $urpm->{log}(N("building hdlist [%s]", "$urpm->{statedir}/$medium->{hdlist}"));
- #- finish building operation of hdlist.
- $urpm->build_hdlist(start => $medium->{start},
- end => $medium->{end},
- dir => "$urpm->{cachedir}/headers",
- hdlist => "$urpm->{statedir}/$medium->{hdlist}",
- );
- #- synthesis needs to be created, since the medium has been built from rpm files.
- eval { $urpm->build_synthesis(
- start => $medium->{start},
- end => $medium->{end},
- synthesis => "$urpm->{statedir}/synthesis.$medium->{hdlist}",
- ) };
- if ($@) {
- #- XXX this happens when building a synthesis for a local media from RPMs... why ?
- $urpm->{error}(N("Unable to build synthesis file for medium \"%s\". Your hdlist file may be corrupted.", $medium->{name}));
- $urpm->{error}($@);
- unlink "$urpm->{statedir}/synthesis.$medium->{hdlist}";
- } else {
- $urpm->{log}(N("built hdlist synthesis file for medium \"%s\"", $medium->{name}));
- }
- #- keep in mind we have a modified database, sure at this point.
- $urpm->{modified} = 1;
- } elsif ($medium->{synthesis}) {
- if ($second_pass) {
- if ($medium->{virtual}) {
- my ($path) = $medium->{url} =~ m!^(?:file:/*)?(/[^/].*[^/])/*\Z!;
- my $with_hdlist_file = "$path/$medium->{with_hdlist}";
- if ($path) {
- $urpm->{log}(N("examining synthesis file [%s]", $with_hdlist_file));
- ($medium->{start}, $medium->{end}) = $urpm->parse_synthesis($with_hdlist_file);
- }
- } else {
- $urpm->{log}(N("examining synthesis file [%s]", "$urpm->{statedir}/synthesis.$medium->{hdlist}"));
- ($medium->{start}, $medium->{end}) = $urpm->parse_synthesis("$urpm->{statedir}/synthesis.$medium->{hdlist}");
- }
- }
- } else {
- if ($second_pass) {
- $urpm->{log}(N("examining hdlist file [%s]", "$urpm->{statedir}/$medium->{hdlist}"));
- ($medium->{start}, $medium->{end}) = $urpm->parse_hdlist("$urpm->{statedir}/$medium->{hdlist}", 1);
- }
- #- check if the synthesis file can be built.
- if (($second_pass || $medium->{modified_synthesis}) && !$medium->{modified}) {
- unless ($medium->{virtual}) {
- eval { $urpm->build_synthesis(
- start => $medium->{start},
- end => $medium->{end},
- synthesis => "$urpm->{statedir}/synthesis.$medium->{hdlist}",
- ) };
- if ($@) {
- $urpm->{error}(N("Unable to build synthesis file for medium \"%s\". Your hdlist file may be corrupted.", $medium->{name}));
- $urpm->{error}($@);
- unlink "$urpm->{statedir}/synthesis.$medium->{hdlist}";
- } else {
- $urpm->{log}(N("built hdlist synthesis file for medium \"%s\"", $medium->{name}));
- }
- }
- #- keep in mind we have modified database, sure at this point.
- $urpm->{modified} = 1;
- }
- }
- $options{callback} && $options{callback}('done', $medium->{name});
+ _update_medium_second_pass($urpm, $medium, $second_pass, $options{callback});
}
- #- clean headers cache directory to remove everything that is no longer
- #- useful according to the depslist.
if ($urpm->{modified}) {
if ($options{noclean}) {
- local $_;
- my %headers;
- my $dh = $urpm->opendir_safe("$urpm->{cachedir}/headers");
- if ($dh) {
- while (defined($_ = readdir $dh)) {
- m|^([^/]*-[^-]*-[^-]*\.[^\.]*)(?::\S*)?$| and $headers{$1} = $_;
- }
- closedir $dh;
- }
- $urpm->{log}(N("found %d headers in cache", scalar(keys %headers)));
- foreach (@{$urpm->{depslist}}) {
- delete $headers{$_->fullname};
- }
- $urpm->{log}(N("removing %d obsolete headers in cache", scalar(keys %headers)));
- foreach (values %headers) {
- unlink "$urpm->{cachedir}/headers/$_";
- }
+ #- clean headers cache directory to remove everything that is no longer
+ #- useful according to the depslist.
+ remove_obsolete_headers_in_cache($urpm);
}
-
#- write config files in any case
$urpm->write_config;
dump_proxy_config();
+ } elsif ($urpm->{md5sum_modified}) {
+ #- NB: in case of $urpm->{modified}, write_MD5SUM is called in write_config above
+ write_MD5SUM($urpm);
}
generate_media_names($urpm);
$options{nolock} or $urpm->unlock_urpmi_db;
- $nopubkey or $urpm->unlock_rpm_db;
+ $options{nopubkey} or $urpm->unlock_rpm_db;
}
#- clean params and depslist computation zone.
@@ -2113,18 +2121,12 @@ sub register_rpms {
/\.(?:rpm|spec)$/ or $error = 1, $urpm->{error}(N("invalid rpm file name [%s]", $_)), next;
#- if that's an URL, download.
- if (my ($basename) = m!^[^:]*:/.*/([^/]*\.(?:rpm|spec))\z!) {
+ if (protocol_from_url($_)) {
+ my $basename = basename($_);
unlink "$urpm->{cachedir}/partial/$basename";
eval {
$urpm->{log}(N("retrieving rpm file [%s] ...", $_));
- $urpm->{sync}(
- {
- dir => "$urpm->{cachedir}/partial",
- quiet => 1,
- proxy => get_proxy(),
- },
- $_,
- );
+ sync_webfetch($urpm, undef, [$_], { quiet => 1 });
$urpm->{log}(N("...retrieving done"));
$_ = "$urpm->{cachedir}/partial/$basename";
};
@@ -2208,11 +2210,10 @@ sub search_packages {
#- we assume that if there is at least one package providing
#- the resource exactly, this should be the best one; but we
#- first check if one of the packages has the same name as searched.
- if ((my @l2) = grep { $_->name eq $v } @l) {
- $exact{$v} = join '|', map { $_->id } @l2;
- } else {
- $exact{$v} = join '|', map { $_->id } @l;
+ if (my @l2 = grep { $_->name eq $v } @l) {
+ @l = @l2;
}
+ $exact{$v} = join('|', map { $_->id } @l);
next;
}
}
@@ -2328,8 +2329,9 @@ sub resolve_dependencies {
my $file = "$urpm->{cachedir}/partial/parallel.cz";
unlink $file;
foreach (@{$urpm->{media}}) {
- defined $_->{start} && defined $_->{end} or next;
- system "cat '$urpm->{statedir}/synthesis.$_->{hdlist}' >> '$file'";
+ is_valid_medium($_) or next;
+ my $f = statedir_synthesis($urpm, $_);
+ system "cat '$f' >> '$file'";
}
#- let each node determine what is requested, according to handler given.
$urpm->{parallel_handler}->parallel_resolve_dependencies($file, $urpm, $state, $requested, %options);
@@ -2340,8 +2342,7 @@ sub resolve_dependencies {
$db = new URPM;
$db->parse_synthesis($options{rpmdb});
} else {
- $db = URPM::DB::open($urpm->{root});
- $db or $urpm->{fatal}(9, N("unable to open rpmdb"));
+ $db = db_open_or_die($urpm, $urpm->{root});
}
my $sig_handler = sub { undef $db; exit 3 };
@@ -2401,8 +2402,7 @@ sub create_transaction {
$db = new URPM;
$db->parse_synthesis($options{rpmdb});
} else {
- $db = URPM::DB::open($urpm->{root});
- $db or $urpm->{fatal}(9, N("unable to open rpmdb"));
+ $db = db_open_or_die($urpm, $urpm->{root});
}
my $sig_handler = sub { undef $db; exit 3 };
@@ -2436,8 +2436,7 @@ sub get_packages_list {
#- associated to a null list.
sub get_source_packages {
my ($urpm, $packages, %options) = @_;
- my ($id, $error, @list_error, %protected_files, %local_sources, @list, %fullname2id, %file2fullnames, %examined);
- local $_;
+ my (%protected_files, %local_sources, %fullname2id);
#- build association hash to retrieve id and examine all list files.
foreach (keys %$packages) {
@@ -2452,6 +2451,7 @@ sub get_source_packages {
#- 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;
}
@@ -2461,14 +2461,15 @@ sub get_source_packages {
if ($dh) {
while (defined(my $filename = readdir $dh)) {
my $filepath = "$urpm->{cachedir}/rpms/$filename";
- next if -d $filepath;
- if (!$options{clean_all} && -s _) {
+ 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));
- next;
} elsif (keys(%{$file2fullnames{$filename} || {}}) == 1) {
my ($fullname) = keys(%{$file2fullnames{$filename} || {}});
- if (defined($id = delete $fullname2id{$fullname})) {
+ if (defined(my $id = delete $fullname2id{$fullname})) {
$local_sources{$id} = $filepath;
} else {
$options{clean_other} && ! exists $protected_files{$filepath} and unlink $filepath;
@@ -2476,30 +2477,28 @@ sub get_source_packages {
} else {
$options{clean_other} && ! exists $protected_files{$filepath} and unlink $filepath;
}
- } else {
- unlink $filepath; #- this file should be removed or is already empty.
}
}
closedir $dh;
}
- #- clean download directory, do it here even if this is not the best moment.
if ($options{clean_all}) {
- require File::Path;
- File::Path::rmtree(["$urpm->{cachedir}/partial"]);
- mkdir "$urpm->{cachedir}/partial", 0755;
+ #- clean download directory, do it here even if this is not the best moment.
+ clean_dir("$urpm->{cachedir}/partial");
}
+ my ($error, @list_error, @list, %examined);
+
foreach my $medium (@{$urpm->{media} || []}) {
my (%sources, %list_examined, $list_warning);
- if (defined $medium->{start} && defined $medium->{end} && !$medium->{ignore}) {
+ if (is_valid_medium($medium) && !$medium->{ignore}) {
#- always prefer a list file if available.
- my $listfile = $medium->{list} ? "$urpm->{statedir}/$medium->{list}" : '';
+ my $listfile = $medium->{list} ? statedir_list($urpm, $medium) : '';
if (!$listfile && $medium->{virtual}) {
- my ($dir) = $medium->{url} =~ m!^(?:removable[^:]*:/|file:/)?(/.*)!;
+ my $dir = file_from_local_url($medium->{url});
my $with_hdlist_dir = reduce_pathname($dir . ($medium->{with_hdlist} ? "/$medium->{with_hdlist}" : "/.."));
- my $local_list = $medium->{with_hdlist} =~ /hd(list.*)\.cz$/ ? $1 : 'list';
+ my $local_list = 'list' . _hdlist_suffix($medium);
$listfile = reduce_pathname("$with_hdlist_dir/../$local_list");
-s $listfile or $listfile = "$dir/list";
}
@@ -2515,7 +2514,7 @@ sub get_source_packages {
next;
} elsif (keys(%{$file2fullnames{$filename} || {}}) == 1) {
my ($fullname) = keys(%{$file2fullnames{$filename} || {}});
- if (defined($id = $fullname2id{$fullname})) {
+ if (defined(my $id = $fullname2id{$fullname})) {
if (!/\.delta\.rpm$/ || $urpm->is_delta_installable($urpm->{depslist}[$id], $options{root})) {
$sources{$id} = $medium->{virtual} ? "$medium->{url}/$_" : $_;
}
@@ -2549,7 +2548,7 @@ sub get_source_packages {
my ($fullname) = keys(%{$file2fullnames{$fi} || {}});
unless (exists($list_examined{$fullname})) {
++$list_warning;
- if (defined($id = $fullname2id{$fullname})) {
+ if (defined(my $id = $fullname2id{$fullname})) {
if ($fi !~ /\.delta\.rpm$/ || $urpm->is_delta_installable($urpm->{depslist}[$id], $options{root})) {
$sources{$id} = "$medium->{url}/" . $fi;
}
@@ -2558,7 +2557,7 @@ sub get_source_packages {
}
}
}
- $list_warning && $medium->{list} && -r "$urpm->{statedir}/$medium->{list}" && -f _
+ $list_warning && $medium->{list} && -r 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) {
@@ -2591,8 +2590,7 @@ sub is_delta_installable {
my $f = $pkg->filename;
my $n = $pkg->name;
my ($v_match) = $f =~ /^\Q$n\E-(.*)_.+\.delta\.rpm$/;
- my $db = URPM::DB::open($root)
- or $urpm->{fatal}(9, N("unable to open rpmdb"));
+ my $db = db_open_or_die($urpm, $root);
my $v_installed;
$db->traverse(sub {
my ($p) = @_;
@@ -2607,7 +2605,7 @@ sub download_source_packages {
my %sources = %$local_sources;
my %error_sources;
- $urpm->exlock_urpmi_db unless $options{nolock};
+ $urpm->lock_urpmi_db('exclusive') if !$options{nolock};
$urpm->copy_packages_of_removable_media($list, \%sources, %options) or return;
$urpm->download_packages_of_distant_media($list, \%sources, \%error_sources, %options);
$urpm->unlock_urpmi_db unless $options{nolock};
@@ -2618,72 +2616,55 @@ sub download_source_packages {
#- lock policy concerning chroot :
# - lock rpm db in chroot
# - lock urpmi db in /
-
-#- safety rpm db locking mechanism
-sub exlock_rpm_db {
- my ($urpm) = @_;
+sub _lock {
+ my ($urpm, $fh_ref, $file, $b_exclusive) = @_;
#- avoid putting a require on Fcntl ':flock' (which is perl and not perl-base).
- my ($LOCK_EX, $LOCK_NB) = (2, 4);
- #- lock urpmi database, but keep lock to wait for an urpmi.update to finish.
- open $RPMLOCK_FILE, ">", "$urpm->{root}/$urpm->{statedir}/.RPMLOCK";
- flock $RPMLOCK_FILE, $LOCK_EX|$LOCK_NB or $urpm->{fatal}(7, N("urpmi database locked"));
+ my ($LOCK_SH, $LOCK_EX, $LOCK_NB) = (1, 2, 4);
+ if ($b_exclusive) {
+ #- lock urpmi database, but keep lock to wait for an urpmi.update to finish.
+ } else {
+ #- create the .LOCK file if needed (and if possible)
+ unless (-e $file) {
+ open(my $f, ">", $file);
+ close $f;
+ }
+ #- lock urpmi database, if the LOCK file doesn't exists no share lock.
+ }
+ my ($sense, $mode) = $b_exclusive ? ('>', $LOCK_EX) : ('<', $LOCK_SH);
+ open $$fh_ref, $sense, $file or return;
+ flock $$fh_ref, $mode|$LOCK_NB or $urpm->{fatal}(7, N("urpmi database locked"));
}
-sub shlock_rpm_db {
+sub lock_rpm_db {
+ my ($urpm, $b_exclusive) = @_;
+ _lock($urpm, \$RPMLOCK_FILE, "$urpm->{root}/$urpm->{statedir}/.RPMLOCK", $b_exclusive);
+}
+sub lock_urpmi_db {
+ my ($urpm, $b_exclusive) = @_;
+ _lock($urpm, \$LOCK_FILE, "$urpm->{statedir}/.LOCK", $b_exclusive);
+}
+#- deprecated
+sub exlock_urpmi_db {
my ($urpm) = @_;
- #- avoid putting a require on Fcntl ':flock' (which is perl and not perl-base).
- my ($LOCK_SH, $LOCK_NB) = (1, 4);
- #- create the .LOCK file if needed (and if possible)
- unless (-e "$urpm->{root}/$urpm->{statedir}/.RPMLOCK") {
- open $RPMLOCK_FILE, ">", "$urpm->{root}/$urpm->{statedir}/.RPMLOCK";
- close $RPMLOCK_FILE;
- }
- #- lock urpmi database, if the LOCK file doesn't exists no share lock.
- open $RPMLOCK_FILE, "$urpm->{root}/$urpm->{statedir}/.RPMLOCK" or return;
- flock $RPMLOCK_FILE, $LOCK_SH|$LOCK_NB or $urpm->{fatal}(7, N("urpmi database locked"));
+ lock_urpmi_db($urpm, 'exclusive');
}
-sub unlock_rpm_db {
- my ($_urpm) = @_;
+sub _unlock {
+ my ($fh_ref) = @_;
#- avoid putting a require on Fcntl ':flock' (which is perl and not perl-base).
my $LOCK_UN = 8;
#- now everything is finished.
#- release lock on database.
- flock $RPMLOCK_FILE, $LOCK_UN;
- close $RPMLOCK_FILE;
-}
-
-sub exlock_urpmi_db {
- my ($urpm) = @_;
- #- avoid putting a require on Fcntl ':flock' (which is perl and not perl-base).
- my ($LOCK_EX, $LOCK_NB) = (2, 4);
- #- lock urpmi database, but keep lock to wait for an urpmi.update to finish.
- open $LOCK_FILE, ">", "$urpm->{statedir}/.LOCK";
- flock $LOCK_FILE, $LOCK_EX|$LOCK_NB or $urpm->{fatal}(7, N("urpmi database locked"));
+ flock $$fh_ref, $LOCK_UN;
+ close $$fh_ref;
}
-
-sub shlock_urpmi_db {
- my ($urpm) = @_;
- #- avoid putting a require on Fcntl ':flock' (which is perl and not perl-base).
- my ($LOCK_SH, $LOCK_NB) = (1, 4);
- #- create the .LOCK file if needed (and if possible)
- unless (-e "$urpm->{statedir}/.LOCK") {
- open $LOCK_FILE, ">", "$urpm->{statedir}/.LOCK";
- close $LOCK_FILE;
- }
- #- lock urpmi database, if the LOCK file doesn't exists no share lock.
- open $LOCK_FILE, "$urpm->{statedir}/.LOCK" or return;
- flock $LOCK_FILE, $LOCK_SH|$LOCK_NB or $urpm->{fatal}(7, N("urpmi database locked"));
+sub unlock_rpm_db {
+ my ($_urpm) = @_;
+ _unlock(\$RPMLOCK_FILE);
}
-
sub unlock_urpmi_db {
my ($_urpm) = @_;
- #- avoid putting a require on Fcntl ':flock' (which is perl and not perl-base).
- my $LOCK_UN = 8;
- #- now everything is finished.
- #- release lock on database.
- flock $LOCK_FILE, $LOCK_UN;
- close $LOCK_FILE;
+ _unlock(\$LOCK_FILE);
}
sub copy_packages_of_removable_media {
@@ -2697,28 +2678,28 @@ sub copy_packages_of_removable_media {
#- examine if given medium is already inside a removable device.
my $check_notfound = sub {
my ($id, $dir, $removable) = @_;
- $dir and $urpm->try_mounting($dir, $removable);
- if (!$dir || -e $dir) {
- foreach (values %{$list->[$id]}) {
- chomp;
- m!^(removable[^:]*:/|file:/)?(/.*/([^/]*)$)! or next;
- unless ($dir) {
- $dir = $2;
- $urpm->try_mounting($dir, $removable);
- }
- -r $2 or return 1;
+ if ($dir) {
+ $urpm->try_mounting($dir, $removable);
+ -e $dir or return 2;
+ }
+ foreach (values %{$list->[$id]}) {
+ chomp;
+ my $dir_ = file_from_local_url($_) or next;
+ $dir_ =~ m!/.*/! or next; #- is this really needed??
+ unless ($dir) {
+ $dir = $dir_;
+ $urpm->try_mounting($dir, $removable);
}
- } else {
- return 2;
+ -r $dir_ or return 1;
}
- return 0;
+ 0;
};
#- removable media have to be examined to keep mounted the one that has
#- more packages than others.
my $examine_removable_medium = sub {
my ($id, $device) = @_;
my $medium = $urpm->{media}[$id];
- if (my ($dir) = $medium->{url} =~ m!^(?:(?:removable[^:]*|file):/)?(/.*)!) {
+ if (my $dir = file_from_local_url($medium->{url})) {
#- the directory given does not exist and may be accessible
#- by mounting some other directory. Try to figure it out and mount
#- everything that might be necessary.
@@ -2734,7 +2715,11 @@ sub copy_packages_of_removable_media {
if (-e $dir) {
while (my ($i, $url) = each %{$list->[$id]}) {
chomp $url;
- my ($filepath, $filename) = $url =~ m!^(?:removable[^:]*:/|file:/)?(/.*/([^/]*))! or next;
+ my ($filepath, $filename) = do {
+ my $f = file_from_local_url($url) or next;
+ $f =~ m!/.*/! or next; #- is this really needed??
+ dirname($f), basename($f);
+ };
if (-r $filepath) {
#- we should assume a possibly buggy removable device...
#- First, copy in partial cache, and if the package is still good,
@@ -2769,7 +2754,7 @@ sub copy_packages_of_removable_media {
#- examine non removable device but that may be mounted.
if ($medium->{removable}) {
push @{$removables{$medium->{removable}} ||= []}, $_;
- } elsif (my ($dir) = $medium->{url} =~ m!^(?:removable[^:]*:/|file:/)?(/.*)!) {
+ } elsif (my $dir = file_from_local_url($medium->{url})) {
-e $dir || $urpm->try_mounting($dir) or
$urpm->{error}(N("unable to access medium \"%s\"", $medium->{name})), next;
}
@@ -2818,11 +2803,12 @@ sub download_packages_of_distant_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;
- if ($url =~ m!^(removable[^:]*:/|file:/)?(/.*\.rpm)\Z!) {
- if (-r $2) {
- $sources->{$i} = $2;
+ 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} = $2;
+ $error_sources->{$i} = $local_file;
}
} elsif ($url =~ m!^([^:]*):/(.*/([^/]*\.rpm))\Z!) {
$distant_sources{$i} = "$1:/$2"; #- will download now
@@ -2835,20 +2821,8 @@ sub download_packages_of_distant_media {
if (%distant_sources) {
eval {
$urpm->{log}(N("retrieving rpm files from medium \"%s\"...", $urpm->{media}[$n]{name}));
- $urpm->{sync}(
- {
- dir => "$urpm->{cachedir}/partial",
- quiet => $options{quiet},
- limit_rate => $options{limit_rate},
- resume => $options{resume},
- compress => $options{compress},
- callback => $options{callback},
- proxy => get_proxy($urpm->{media}[$n]{name}),
- media => $urpm->{media}[$n]{name},
- retry => $urpm->{options}{retry},
- },
- values %distant_sources,
- );
+ sync_webfetch($urpm, $urpm->{media}[$n], [ values %distant_sources ],
+ \%options, resume => $options{resume}, callback => $options{callback});
$urpm->{log}(N("...retrieving done"));
};
$@ and $urpm->{error}(N("...retrieving failed: %s", $@));
@@ -2975,9 +2949,9 @@ sub install {
local $_;
while (<$CHILD_RETURNS>) {
chomp;
- if (/^::logger_id:(\d+)(?::(\d+))?/) {
+ if (/^::logger_id:(\d*):(\d*)/) {
$urpm->{logger_id} = $1;
- $2 and $urpm->{logger_count} = $2;
+ $urpm->{logger_count} = $2 if $2;
} else {
push @l, $_;
}
@@ -2996,9 +2970,7 @@ sub install {
}
#- beware this can be a child process or the main process now...
- my $db = URPM::DB::open($urpm->{root}, !$options{test}); #- open in read/write mode unless testing installation.
-
- $db or $urpm->{fatal}(9, N("unable to open rpmdb"));
+ my $db = db_open_or_die($urpm, $urpm->{root}, !$options{test}); #- open in read/write mode unless testing installation.
my $trans = $db->create_transaction($urpm->{root});
if ($trans) {
@@ -3084,7 +3056,10 @@ sub install {
close $ERROR_OUTPUT;
#- keep safe exit now (with destructor call).
exit 0;
- } else { #- parent process
+ } else {
+ #- when non-forking
+ # !!! BUG: this part of the code is not called when forking !!!
+ # !!! BUG: when forking %readmes is empty, since the child is not passing this information to its parent !!!
if ($::verbose >= 0 && keys %readmes) {
foreach (keys %readmes) {
print "-" x 70, "\n", N("More information on package %s", $readmes{$_}), "\n";
@@ -3123,11 +3098,9 @@ sub find_packages_to_remove {
#- invoke parallel finder.
$urpm->{parallel_handler}->parallel_find_remove($urpm, $state, $l, %options, find_packages_to_remove => 1);
} else {
- my $db = URPM::DB::open($options{root});
+ my $db = db_open_or_die($urpm, $options{root});
my (@m, @notfound);
- $db or $urpm->{fatal}(9, N("unable to open rpmdb"));
-
if (!$options{matches}) {
foreach (@$l) {
my ($n, $found);
@@ -3264,25 +3237,29 @@ sub unselected_packages {
sub uniq { my %l; $l{$_} = 1 foreach @_; grep { delete $l{$_} } @_ }
sub translate_why_unselected {
- my ($urpm, $state, @l) = @_;
-
- map {
- my $rb = $state->{rejected}{$_}{backtrack};
- my @froms = keys %{$rb->{closure} || {}};
- my @unsatisfied = @{$rb->{unsatisfied} || []};
- my $s = join ", ", (
- (map { N("due to missing %s", $_) } @froms),
- (map { N("due to unsatisfied %s", $_) } uniq(map {
- #- XXX in theory we shouldn't need this, dependencies (and not ids) should
- #- already be present in @unsatisfied. But with biarch packages this is
- #- not always the case.
- /\D/ ? $_ : scalar($urpm->{depslist}[$_]->fullname);
- } @unsatisfied)),
- $rb->{promote} && !$rb->{keep} ? N("trying to promote %s", join(", ", @{$rb->{promote}})) : @{[]},
- $rb->{keep} ? N("in order to keep %s", join(", ", @{$rb->{keep}})) : @{[]},
- );
- $_ . ($s ? " ($s)" : '');
- } @l;
+ my ($urpm, $state, @fullnames) = @_;
+
+ join("\n", map { translate_why_unselected_one($urpm, $state, $_) } sort @fullnames);
+}
+
+sub translate_why_unselected_one {
+ my ($urpm, $state, $fullname) = @_;
+
+ my $rb = $state->{rejected}{$fullname}{backtrack};
+ my @froms = keys %{$rb->{closure} || {}};
+ my @unsatisfied = @{$rb->{unsatisfied} || []};
+ my $s = join ", ", (
+ (map { N("due to missing %s", $_) } @froms),
+ (map { N("due to unsatisfied %s", $_) } uniq(map {
+ #- XXX in theory we shouldn't need this, dependencies (and not ids) should
+ #- already be present in @unsatisfied. But with biarch packages this is
+ #- not always the case.
+ /\D/ ? $_ : scalar($urpm->{depslist}[$_]->fullname);
+ } @unsatisfied)),
+ $rb->{promote} && !$rb->{keep} ? N("trying to promote %s", join(", ", @{$rb->{promote}})) : (),
+ $rb->{keep} ? N("in order to keep %s", join(", ", @{$rb->{keep}})) : (),
+ );
+ $fullname . ($s ? " ($s)" : '');
}
sub removed_packages {
@@ -3341,14 +3318,12 @@ sub check_sources_signatures {
$verif =~ s/\n//g;
$invalid_sources{$filepath} = N("Invalid signature (%s)", $verif);
} else {
- unless ($medium &&
- defined $medium->{start} && $medium->{start} <= $id &&
- defined $medium->{end} && $id <= $medium->{end})
+ unless ($medium && is_valid_medium($medium) &&
+ $medium->{start} <= $id && $id <= $medium->{end})
{
$medium = undef;
foreach (@{$urpm->{media}}) {
- defined $_->{start} && $_->{start} <= $id
- && defined $_->{end} && $id <= $_->{end}
+ is_valid_medium($_) && $_->{start} <= $id && $id <= $_->{end}
and $medium = $_, last;
}
}
@@ -3393,11 +3368,7 @@ sub check_sources_signatures {
sub dump_description_file {
my ($urpm, $media_name) = @_;
- open my $fh, '<', "$urpm->{statedir}/descriptions.$media_name"
- or return ();
- my @slurp = <$fh>;
- close $fh;
- return @slurp;
+ cat_("$urpm->{statedir}/descriptions.$media_name");
}
#- get reason of update for packages to be updated
@@ -3432,20 +3403,21 @@ sub get_updates_description {
#- parse an MD5SUM file from a mirror
sub get_md5sum {
- my ($path, $basename) = @_;
+ my ($md5sum_file, $f) = @_;
+ my $basename = basename($f);
my ($retrieved_md5sum) = map {
my ($md5sum, $file) = m|(\S+)\s+(?:\./)?(\S+)|;
- $file && $file eq $basename ? $md5sum : ();
- } cat_($path);
+ $file && $file eq $basename ? $md5sum : @{[]};
+ } cat_($md5sum_file);
$retrieved_md5sum;
}
sub parse_md5sum {
- my ($urpm, $path, $basename) = @_;
+ my ($urpm, $md5sum_file, $basename) = @_;
$urpm->{log}(N("examining MD5SUM file"));
- my $retrieved_md5sum = get_md5sum($path, $basename)
+ my $retrieved_md5sum = get_md5sum($md5sum_file, $basename)
or $urpm->{log}(N("warning: md5sum for %s unavailable in MD5SUM file", $basename));
return $retrieved_md5sum;
}
@@ -3456,16 +3428,17 @@ sub recompute_local_md5sum {
#- force downloading the file again, else why a force option has been defined ?
delete $medium->{md5sum};
} else {
- unless ($medium->{md5sum}) {
- $urpm->{log}(N("computing md5sum of existing source hdlist (or synthesis)"));
- if ($medium->{synthesis}) {
- -e "$urpm->{statedir}/synthesis.$medium->{hdlist}" and
- $medium->{md5sum} = md5sum("$urpm->{statedir}/synthesis.$medium->{hdlist}");
- } else {
- -e "$urpm->{statedir}/$medium->{hdlist}" and
- $medium->{md5sum} = md5sum("$urpm->{statedir}/$medium->{hdlist}");
- }
- }
+ compute_local_md5sum($urpm, $medium) if !$medium->{md5sum};
+ }
+}
+
+sub compute_local_md5sum {
+ my ($urpm, $medium) = @_;
+
+ $urpm->{log}(N("computing md5sum of existing source hdlist (or synthesis)"));
+ my $f = statedir_hdlist_or_synthesis($urpm, $medium);
+ if (-e $f) {
+ $medium->{md5sum} = md5sum($f);
}
}