]> git.deb.at Git - deb/packages.git/blob - lib/Packages/DoDownload.pm
Don't let come virtual packages in our way
[deb/packages.git] / lib / Packages / DoDownload.pm
1 package Packages::DoDownload;
2
3 use strict;
4 use warnings;
5
6 use CGI ();
7 use DB_File;
8 use Benchmark ':hireswallclock';
9 use Exporter;
10
11 use Deb::Versions;
12 use Packages::I18N::Locale;
13 use Packages::HTML ();
14 use Packages::Search qw( :all );
15 use Packages::Config qw( $HOME $DBDIR @SUITES @ARCHIVES @SECTIONS @ARCHITECTURES $SEARCH_URL );
16 use Packages::CGI;
17 use Packages::DB;
18
19 our @ISA = qw( Exporter );
20 our @EXPORT = qw( do_download );
21
22 # TODO: find a way to get the U.S. mirror list from a more authoritive
23 # location automatically. might not be overly smart to automatize it
24 # completely, since I hand pick sites that are up-to-date, fast, and
25 # have HTTP on a reasonably short URL
26 #   -- Joy
27
28 # hint:
29 # grep-dctrl -F Site,Alias -e '(udel|bigfoot|kernel|crosslink|internap|cerias|lcs.mit|progeny)' Mirrors.masterlist | timestamps/archive_mirror_check.py
30 our @north_american_sites = (
31         "ftp.us.debian.org/debian",
32         "http.us.debian.org/debian",
33         "ftp.debian.org/debian",
34 #       "ftp.ca.debian.org/debian",
35         "ftp.egr.msu.edu/debian",
36         "mirrors.kernel.org/debian",
37         "archive.progeny.com/debian",
38         "debian.crosslink.net/debian",
39         "ftp-mirror.internap.com/pub/debian",
40         "ftp.cerias.purdue.edu/pub/os/debian",
41         "ftp.lug.udel.edu/debian",
42         "debian.lcs.mit.edu/debian",
43         "debian.teleglobe.net",
44         "debian.rutgers.edu",
45         "debian.oregonstate.edu/debian",
46         );
47 our @european_sites = (
48         "ftp.de.debian.org/debian",
49         "ftp.at.debian.org/debian",
50         "ftp.bg.debian.org/debian",
51         "ftp.cz.debian.org/debian",
52         "ftp.dk.debian.org/debian",
53         "ftp.ee.debian.org/debian",
54         "ftp.fi.debian.org/debian",
55         "ftp.fr.debian.org/debian",
56         "ftp.hr.debian.org/debian",
57         "ftp.hu.debian.org/debian",
58         "ftp.ie.debian.org/debian",
59         "ftp.is.debian.org/debian",
60         "ftp.it.debian.org/debian",
61         "ftp.nl.debian.org/debian",
62         "ftp.no.debian.org/debian",
63         "ftp.pl.debian.org/debian",
64         "ftp.si.debian.org/debian",
65         "ftp.es.debian.org/debian",
66         "ftp.se.debian.org/debian",
67         "ftp.tr.debian.org/debian",
68         "ftp.uk.debian.org/debian",
69         );
70 our @south_american_sites = (
71         "ftp.br.debian.org/debian",
72         "ftp.cl.debian.org/debian",
73         );
74 our @australian_sites = (
75         "ftp.au.debian.org/debian",
76         "ftp.wa.au.debian.org/debian",
77         "ftp.nz.debian.org/debian",
78         );
79 our @asian_sites = (
80         "ftp.jp.debian.org/debian",
81 #       "ftp.kr.debian.org/debian",
82         "linux.csie.nctu.edu.tw/debian",
83         "debian.linux.org.tw/debian",
84         "linux.cdpa.nsysu.edu.tw/debian",
85         ); 
86
87 our @volatile_european_sites = (
88         "volatile.debian.net/debian-volatile",
89         "ftp2.de.debian.org/debian-volatile",
90         "ftp.sk.debian.org/debian-volatile",
91                                );
92 our @backports_european_sites = (
93         "www.backports.org/debian",
94         "debian.sil.at/backports.org/",
95         "backports.debian.or.at/backports.org",
96         "mirror.realroute.net/backports.org",
97         "backports.cisbg.com",
98         "backports.linuxdediziert.de/backports.org",
99         "debian.netcologne.de/debian-backports",
100         "ftp.de.debian.org/backports.org",
101         "mirror.buildd.net/backports.org",
102         "ftp.estpak.ee/backports.org",
103         "debian.acantho.net/backports.org",
104         "backports.essentkabel.com/backports.org",
105         "backports.sipo.nl",
106         "ftp.tuke.sk",
107                                );
108 our @backports_asian_sites = (
109         "backports.mithril-linux.org",
110                              );
111 our @backports_australian_sites = (
112         "mirror.linux.org.au/backports.org",
113                                   );
114 our @amd64_european_sites = (
115         "amd64.debian.net/debian",
116         "ftp.de.debian.org/debian-amd64/debian",
117         "bach.hpc2n.umu.se/debian-amd64/debian",
118         "bytekeeper.as28747.net/debian-amd64/debian",
119         "mirror.switch.ch/debian-amd64/debian",
120         "ftp.nl.debian.org/debian-amd64/debian",
121                             );
122 our @amd64_asian_sites = (
123         "hanzubon.jp/debian-amd64/debian",
124                          );
125 our @amd64_north_american_sites = (
126         "mirror.espri.arizona.edu/debian-amd64/debian",
127                                   );
128 our @kfreebsd_north_american_sites = (
129         "www.gtlib.gatech.edu/pub/gnuab/debian",
130                                      );
131 our @kfreebsd_european_sites = (
132         # master site, aka ftp.gnuab.org
133         "kfreebsd-gnu.debian.net/debian",
134         "ftp.easynet.be/ftp/gnuab/debian",
135         "ftp.de.debian.org/debian-kfreebsd",
136                                );
137 our @nonus_north_american_sites = (
138 #       "ftp.ca.debian.org/debian-non-US",
139         "debian.yorku.ca/debian/non-US",
140         "mirror.direct.ca/linux/debian-non-US",
141         );
142 our @nonus_european_sites = (
143         "non-us.debian.org/debian-non-US",
144         "ftp.de.debian.org/debian-non-US",
145         "ftp.at.debian.org/debian-non-US",
146         "ftp.bg.debian.org/debian-non-US",
147         "ftp.cz.debian.org/debian-non-US",
148         "ftp.fi.debian.org/debian-non-US",
149         "ftp.fr.debian.org/debian-non-US",
150         "ftp.hr.debian.org/debian-non-US",
151         "ftp.hu.debian.org/debian-non-US",
152         "ftp.ie.debian.org/debian-non-US",
153         "ftp.is.debian.org/debian-non-US",
154         "ftp.it.debian.org/debian-non-US",
155         "ftp.nl.debian.org/debian-non-US",
156         "ftp.no.debian.org/debian-non-US",
157         "ftp.pl.debian.org/debian/non-US",
158         "ftp.si.debian.org/debian-non-US",
159         "ftp.es.debian.org/debian-non-US",
160         "ftp.se.debian.org/debian-non-US",
161         "ftp.tr.debian.org/debian-non-US",
162         "ftp.uk.debian.org/debian/non-US",
163         );
164 our @nonus_australian_sites = (
165         "ftp.au.debian.org/debian-non-US",
166         "ftp.wa.au.debian.org/debian-non-US",
167         "ftp.nz.debian.org/debian-non-US",
168         );
169 our @nonus_asian_sites = (
170         "ftp.jp.debian.org/debian-non-US",
171 #       "ftp.kr.debian.org/debian-non-US",
172         "linux.csie.nctu.edu.tw/debian-non-US",
173         "debian.linux.org.tw/debian-non-US",
174         "linux.cdpa.nsysu.edu.tw/debian-non-US",
175         );
176 our @nonus_south_american_sites = (
177         "ftp.br.debian.org/debian-non-US",
178         "ftp.cl.debian.org/debian-non-US",
179         );
180
181 # list of architectures
182 our %arches = (
183         i386    => 'Intel x86',
184         m68k    => 'Motorola 680x0',
185         sparc   => 'SPARC',
186         alpha   => 'Alpha',
187         powerpc => 'PowerPC',
188         arm     => 'ARM',
189         hppa    => 'HP PA-RISC',
190         ia64    => 'Intel IA-64',
191         mips    => 'MIPS',
192         mipsel  => 'MIPS (DEC)',
193         s390    => 'IBM S/390',
194         "hurd-i386" => 'Hurd (i386)',
195         amd64   => 'AMD64',
196         "kfreebsd-i386" => 'GNU/kFreeBSD (i386)'
197 );
198
199 sub do_download {
200     my ($params, $opts, $html_header, $menu, $page_content) = @_;
201
202     if ($params->{errors}{package}) {
203         fatal_error( _g( "package not valid or not specified" ) );
204     }
205     if ($params->{errors}{suite}) {
206         fatal_error( _g( "suite not valid or not specified" ) );
207     }
208     if ($params->{errors}{arch}) {
209         fatal_error( _g( "architecture not valid or not specified" ) );
210     }
211     if (@{$opts->{suite}} > 1) {
212         fatal_error( sprintf( _g( "more than one suite specified for download (%s)" ), "@{$opts->{suite}}" ) );
213     }
214     if (@{$opts->{arch}} > 1) {
215         fatal_error( sprintf( _g( "more than one architecture specified for download (%s)" ), "@{$opts->{arch}}" ) );
216     }
217
218     $opts->{h_sections} = { map { $_ => 1 } @SECTIONS };
219     my $pkg = $opts->{package};
220     my $suite = $opts->{suite}[0];
221     my $arch = $opts->{arch}[0] ||'';
222
223     our (%packages_all);
224     my (@results);
225     my ($final_result, $file, $filen, $md5sum, @file_components, $archive) = ("")x5;
226
227     my $st0 = new Benchmark;
228     unless (@Packages::CGI::fatal_errors) {
229         tie %packages_all, 'DB_File', "$DBDIR/packages_all_$suite.db",
230         O_RDONLY, 0666, $DB_BTREE
231             or die "couldn't tie DB $DBDIR/packages_all_$suite.db: $!";
232         
233         read_entry( \%packages, $pkg, \@results, $opts );
234
235         @results = grep { $_->[7] ne 'v' } @results;
236         unless (@results) {
237             fatal_error( _g( "No such package." )."<br>".
238                          sprintf( _g( '<a href="%s">Search for the package</a>' ), "$SEARCH_URL/$pkg" ) );
239         } else {
240             my $final_result = shift @results;
241             foreach (@results) {
242                 if (version_cmp( $_->[7], $final_result->[7] ) > 0) {
243                     $final_result = $_;
244                 }
245             }
246             
247             debug( "final_result=@$final_result", 1 );
248             $archive = $final_result->[1];
249             my %data = split /\000/, $packages_all{"$pkg $arch $final_result->[7]"};
250             $file = $data{filename};
251             @file_components = split('/', $file);
252             $filen = pop(@file_components);
253             
254             $md5sum = $data{md5sum};
255         }
256     }
257
258     %$html_header = ( title => _g( "Package Download Selection" ),
259                       lang => $opts->{lang},
260                       print_title => 1 );
261
262     if ($file) {
263         if ($arch ne 'all') {
264             $$page_content .= '<h2>'.sprintf( _g('Download Page for <kbd>%s</kbd> on %s machines'), $filen, $arches{$arch} ).'</h2>';
265         } else {
266             $$page_content .= '<h2>'.sprintf( _g('Download Page for <kbd>%s</kbd>'), $filen ).'</h2>';
267         }
268         my $directory = join( '/', @file_components).'/';
269         if ($archive ne 'security' ) {
270             $$page_content .= "<p>".sprintf( _g( 'You can download the requested file from the <tt>%s</tt> subdirectory at any of these sites:' ), $directory )."</p>\n";
271         } else {
272             $$page_content .= "<p>".sprintf( _g( 'You can download the requested file from the <tt>%s</tt> subdirectory at:' ), $directory )."</p>\n";
273         }
274
275         hint(sprintf(_g("If you are running Debian, it's strongly suggested to use a
276             package manager like <a href=\"%s\">aptitude</a> or <a
277             href=\"%s\">synaptic</a> to download and install
278             packages, instead of doing so manually via this website."),
279                      make_url('aptitude','',{arch=>undef}), 
280                      make_url('synaptic','',{arch=>undef}) ) );
281         
282         if ($archive eq 'security') {
283             
284             $$page_content .= "<ul><li><a href=\"http://security.debian.org/debian-security/$file\">security.debian.org/debian-security</a></li></ul>";
285             $$page_content .= '<p>'._g( 'Debian security updates are currently officially distributed only via <tt>security.debian.org</tt>.' ).'</p>';
286         } elsif ($arch eq 'amd64') {
287
288             $$page_content .= print_links( _g( "North America" ), $file, @amd64_north_american_sites );
289             $$page_content .= print_links( _g( "Europe" ), $file, @amd64_european_sites );
290             $$page_content .= print_links( _g( "Asia" ), $file, @amd64_asian_sites );
291
292             $$page_content .= '<p>'._g( 'Note that AMD64 is not officialy included in the Debian archive yet, but the AMD64 porter group keeps their archive in sync with the official archive as close as possible. See the <a href="http://www.debian.org/ports/amd64/">AMD64 ports page</a> for current information.' ).'</p>';
293         } elsif ($arch eq 'kfreebsd-i386') {
294
295             $$page_content .= print_links( _g( "North America" ), $file, @kfreebsd_north_american_sites );
296             $$page_content .= print_links( _g( "Europe" ), $file, @kfreebsd_european_sites );
297         
298             $$page_content .= '<p>'._g( 'Note that GNU/kFreeBSD is not officialy included in the Debian archive yet, but the GNU/kFreeBSD porter group keeps their archive in sync with the official archive as close as possible. See the <a href="http://www.debian.org/ports/kfreebsd-gnu/">GNU/kFreeBSD ports page</a> for current information.' ).'</p>';
299         } elsif ($archive eq 'non-US') {
300
301             $$page_content .= print_links( _g( "North America" ), $file, @nonus_north_american_sites );
302             $$page_content .= print_links( _g( "Europe" ), $file, @nonus_european_sites );
303             $$page_content .= print_links( _g( "Australia and New Zealand" ), $file,
304                                            @nonus_australian_sites );
305             $$page_content .= print_links( _g( "Asia" ), $file, @nonus_asian_sites );
306             $$page_content .= print_links( _g( "South America" ), $file, @nonus_south_american_sites );
307             
308             $$page_content .= '<p>'.sprintf( _g('If none of the above sites are fast enough for you, please see our <a href="%s">complete mirror list</a>.' ), 'http://www.debian.org/mirror/list-non-US' ).'</p>';
309         } elsif ($archive eq 'backports') {
310         
311             $$page_content .= '<div class="cardleft">';
312             $$page_content .= print_links( _g( "Europe" ), $file, @backports_european_sites );
313             $$page_content .= '</div><div class="cardright">';
314             $$page_content .= print_links( _g( "Australia and New Zealand" ), $file,
315                                            @backports_australian_sites );
316             $$page_content .= print_links( _g( "Asia" ), $file, @backports_asian_sites );
317             $$page_content .= '</div>';
318             
319             $$page_content .= '<p style="clear:both">'.sprintf( _g( 'If none of the above sites are fast enough for you, please see our <a href="%s">complete mirror list</a>.'), 'http://www.backports.org/debian/README.mirrors.html' ).'</p>';
320         } elsif ($archive eq 'volatile') {
321             
322             $$page_content .= print_links( _g( "Europe" ), $file, @volatile_european_sites );
323
324             $$page_content .= '<p>'.sprintf( _g( 'If none of the above sites are fast enough for you, please see our <a href="%s">complete mirror list</a>.' ), 'http://volatile.debian.net/mirrors.html' ).'</p>';
325         } elsif ($archive eq 'us') {
326             
327             $$page_content .= '<div class="cardleft">';
328             $$page_content .= print_links( _g( "North America" ), $file, @north_american_sites );
329             $$page_content .= '</div><div class="cardright">';
330             $$page_content .= print_links( _g( "Europe" ), $file, @european_sites );
331             $$page_content .= '</div><div class="cardleft">';
332             $$page_content .= print_links( _g( "Australia and New Zealand" ), $file, @australian_sites );
333             $$page_content .= '</div><div class="cardright">';
334             $$page_content .= print_links( _g( "Asia" ), $file, @asian_sites );
335             $$page_content .= '</div><div class="cardleft">';
336             $$page_content .= print_links( _g( "South America" ), $file, @south_american_sites );
337             $$page_content .= '</div>';
338             
339             $$page_content .= '<p style="clear:both">'.sprintf( _g( 'If none of the above sites are fast enough for you, please see our <a href="%s">complete mirror list</a>.' ), 'http://www.debian.org/mirror/list' ).'</p>';
340         }
341     
342     $$page_content .= '<p>'._g( 'Note that in some browsers you will need to tell your browser you want the file saved to a file. For example, in Firefox or Mozilla, you should hold the Shift key when you click on the URL.' ).'</p>';
343     $$page_content .= "<p>".sprintf( _g( 'The MD5sum for <tt>%s</tt> is <strong>%s</strong>' ), $filen, $md5sum ).'</p>'
344         if $md5sum;
345     }
346 }
347
348 sub print_links {
349     my ( $title, $file, @servers ) = @_;
350
351     my $str = "<p><em>$title</em></p>";
352     $str .= "<ul>";
353     foreach (@servers) {
354         $str .= "<li><a href=\"http://$_/$file\">$_</a></li>\n";
355         # $str .= "<li><a href=\"ftp://$_/$file\">$_</a></li>\n";
356     }
357     $str .= "</ul>";
358
359     return $str;
360 }
361
362 1;