3 ################################################################
5 # Copyright (c) 1995-2014 SUSE Linux Products GmbH
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License version 2 or 3 as
9 # published by the Free Software Foundation.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program (see the file COPYING); if not, write to the
18 # Free Software Foundation, Inc.,
19 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
21 ################################################################
24 unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
34 use File::Path qw(mkpath rmtree);
36 use File::Copy qw(move);
37 use IPC::SysV qw(IPC_PRIVATE S_IRUSR S_IWUSR IPC_CREAT IPC_EXCL SEM_UNDO);
40 Getopt::Long::Configure("no_ignore_case");
47 my $cachedir = "/var/cache/build";
50 my ($pkg, $baseurl, $old_seen) = @_;
52 my $arch = $pkg->{'arch'};
53 $arch = 'src' if $pkg->{'arch'} eq 'nosrc';
54 return if $arch eq 'src' && $opt_nosrc;
55 my $evr = $pkg->{'version'}.'-'.$pkg->{'release'};
56 $evr = "$pkg->{'epoch'}:$evr" if $pkg->{'epoch'};
57 my $loc = $baseurl . $pkg->{'location'};
58 if ($old_seen->{$pkg->{'name'}}->{$arch}) {
59 my $vv = Build::Rpm::verscmp($old_seen->{$pkg->{'name'}}->{$arch}->{'evr'}, $evr, 0);
64 print $old_seen->{$pkg->{'name'}}->{$arch}->{'loc'}."\n";
66 $old_seen->{$pkg->{'name'}}->{$arch}->{'evr'} = $evr;
67 $old_seen->{$pkg->{'name'}}->{$arch}->{'loc'} = $loc;
71 "nosrc" => \$opt_nosrc,
74 "zypp=s" => \$opt_zypp,
75 "cachedir=s" => \$cachedir,
78 $opt_bc = 1 unless $opt_dump || $opt_old;
80 my $old_seen = {}; # for opt_old
81 my @packages; # for opt_dump
88 } elsif ($url =~ /^(?:ftps?|https?):\/\/([^\/]*)\/?/) {
89 my $repoid = Digest::MD5::md5_hex($url);
90 $dir = "$cachedir/$repoid/";
91 $baseurl .= '/' unless $baseurl =~ /\/$/;
92 mkpath("${dir}repodata");
94 #my $key = IPC::SysV::ftok($dir, '1');
95 #if ($sem = IPC::Semaphore->new($key, 1, S_IRUSR | S_IWUSR | IPC_CREAT | IPC_EXCL)) {
98 # $sem = IPC::Semaphore->new($key, 1, S_IRUSR | S_IWUSR | IPC_CREAT);
101 #$sem->op(0, -1, SEM_UNDO);
102 #if (!-f "${dir}repodata/repomd.xml") {
103 system($INC[0].'/download', "${dir}repodata", "${baseurl}repodata/repomd.xml");
105 #$sem->op(0, 1, SEM_UNDO);
110 $dir .= '/' unless $dir =~ /\/$/;
111 $baseurl .= '/' unless $baseurl =~ /\/$/;
113 if (! -s "${dir}repodata/repomd.xml") {
114 die("zypp repo $url is not up to date, please refresh first\n") if $opt_zypp;
115 die("repo $url does not contain a repomd.xml file\n");
119 Build::Rpmmd::parse_repomd("${dir}repodata/repomd.xml", \@primaryfiles);
120 @primaryfiles = grep {$_->{'type'} eq 'primary' && defined($_->{'location'})} @primaryfiles;
121 # print Dumper(\@primaryfiles);
123 for my $f (@primaryfiles) {
124 my $u = "$dir$f->{'location'}";
131 #my $key = IPC::SysV::ftok("${dir}repodata/", '1');
132 #if ($sem = IPC::Semaphore->new($key, 1, S_IRUSR | S_IWUSR | IPC_CREAT | IPC_EXCL)) {
133 # $sem->setval(0, 1);
135 # $sem = IPC::Semaphore->new($key, 1, S_IRUSR | S_IWUSR | IPC_CREAT);
137 #$sem->op(0, -1, SEM_UNDO);
140 $cached = 0 if exists($f->{'size'}) && $f->{'size'} != (-s _);
141 $cached = 0 if !exists($f->{'size'}) && $u !~ /[0-9a-f]{32}-primary/;
144 die("zypp repo $url is not up to date, please refresh first\n") if $opt_zypp;
145 if ($url =~ /^(?:ftps?|https?):\/\/([^\/]*)\/?/) {
146 if (system("$INC[0]/download", "${dir}repodata/", "${baseurl}repodata/" . basename($u))) {
147 die("download failed\n");
150 die("inconsistent repodata in $url\n");
153 #$sem->op(0, 1, SEM_UNDO);
157 open($fh, '<', $u) or die "Error opening $u: $!\n";
159 use IO::Uncompress::Gunzip qw($GunzipError);
160 $fh = new IO::Uncompress::Gunzip $fh or die "Error opening $u: $GunzipError\n";
162 Build::Rpmmd::parse($fh, sub {
164 $_[0]->{'baseurl'} = $baseurl;
165 push @packages, $_[0] if $opt_dump;
168 Build::writedeps(\*STDOUT, $_[0], $baseurl);
170 printold($_[0], $baseurl, $old_seen);
172 }, 'addselfprovides' => 1);
178 print Data::Dumper->Dump([\@packages], ['packages']); # caution: excessive memory consumption!