50ecfc696659ea63b1974259e03dddfa6b5411d1
[openwrt-10.03/.git] / scripts / download.pl
1 #!/usr/bin/env perl
2
3 # Copyright (C) 2006 OpenWrt.org
4 #
5 # This is free software, licensed under the GNU General Public License v2.
6 # See /LICENSE for more information.
7 #
8
9 use strict;
10 use warnings;
11 use File::Basename;
12
13 @ARGV > 2 or die "Syntax: $0 <target dir> <filename> <md5sum> [<mirror> ...]\n";
14
15 my $target = shift @ARGV;
16 my $filename = shift @ARGV;
17 my $md5sum = shift @ARGV;
18 my $scriptdir = dirname($0);
19 my @mirrors;
20 my $ok;
21
22 sub localmirrors {
23         my @mlist;
24         open LM, "$scriptdir/localmirrors" and do {
25             while (<LM>) {
26                         chomp $_;
27                         push @mlist, $_;
28                 }
29                 close LM;
30         };
31         open CONFIG, "<".$ENV{'TOPDIR'}."/.config" and do {
32                 while (<CONFIG>) {
33                         /^CONFIG_LOCALMIRROR="(.+)"/ and do {
34                                 chomp;
35                                 my @local_mirrors = split(/;/, $1);
36                                 push @mlist, @local_mirrors;
37                         };
38                 }
39                 close CONFIG;
40         };
41
42         return @mlist;
43 }
44
45 sub which($) {
46         my $prog = shift;
47         my $res = `which $prog`;
48         $res or return undef;
49         $res =~ /^no / and return undef;
50         $res =~ /not found/ and return undef;
51         return $res;
52 }
53
54 my $md5cmd = which("md5sum");
55 $md5cmd or $md5cmd = which("md5");
56 $md5cmd or die 'no md5 checksum program found, please install md5 or md5sum';
57 chomp $md5cmd;
58
59 sub download
60 {
61         my $mirror = shift;
62         my $options = $ENV{WGET_OPTIONS};
63         $options or $options = "";
64
65         $mirror =~ s/\/$//;
66         if( $mirror =~ /^file:\/\// ) {
67                 my $cache = $mirror;
68                 $cache =~ s/file:\/\///g;
69                 if(system("test -d $cache")) {
70                         print STDERR "Wrong local cache directory -$cache-.\n";
71                         cleanup();
72                         return;
73                 }
74                 if(! -d $target) {
75                         system("mkdir -p $target/");
76                 }
77                 system("cp -vf $cache/$filename $target/$filename.dl") == 0 or return;
78                 system("$md5cmd $target/$filename.dl > \"$target/$filename.md5sum\" ") == 0 or return;
79         } else {
80                 open WGET, "wget -t5 --timeout=20 --no-check-certificate $options -O- \"$mirror/$filename\" |" or die "Cannot launch wget.\n";
81                 open MD5SUM, "| $md5cmd > \"$target/$filename.md5sum\"" or die "Cannot launch md5sum.\n";
82                 open OUTPUT, "> $target/$filename.dl" or die "Cannot create file $target/$filename.dl: $!\n";
83                 my $buffer;
84                 while (read WGET, $buffer, 1048576) {
85                         print MD5SUM $buffer;
86                         print OUTPUT $buffer;
87                 }
88                 close MD5SUM;
89                 close WGET;
90                 close OUTPUT;
91
92                 if (($? >> 8) != 0 ) {
93                         print STDERR "Download failed.\n";
94                         cleanup();
95                         return;
96                 }
97         }
98
99         my $sum = `cat "$target/$filename.md5sum"`;
100         $sum =~ /^(\w+)\s*/ or die "Could not generate md5sum\n";
101         $sum = $1;
102
103         if (($md5sum =~ /\w{32}/) and ($sum ne $md5sum)) {
104                 print STDERR "MD5 sum of the downloaded file does not match (file: $sum, requested: $md5sum) - deleting download.\n";
105                 cleanup();
106                 return;
107         }
108
109         unlink "$target/$filename";
110         system("mv \"$target/$filename.dl\" \"$target/$filename\"");
111         cleanup();
112 }
113
114 sub cleanup
115 {
116         unlink "$target/$filename.dl";
117         unlink "$target/$filename.md5sum";
118 }
119
120 @mirrors = localmirrors();
121
122 foreach my $mirror (@ARGV) {
123         if ($mirror =~ /^\@SF\/(.+)$/) {
124                 # give sourceforge a few more tries, because it redirects to different mirrors
125                 for (1 .. 5) {
126                         push @mirrors, "http://downloads.sourceforge.net/$1";
127                 }
128         } elsif ($mirror =~ /^\@GNU\/(.+)$/) {
129                 push @mirrors, "ftp://ftp.gnu.org/gnu/$1";
130                 push @mirrors, "ftp://ftp.belnet.be/mirror/ftp.gnu.org/gnu/$1";
131                 push @mirrors, "ftp://ftp.mirror.nl/pub/mirror/gnu/$1";
132                 push @mirrors, "http://mirror.switch.ch/ftp/mirror/gnu/$1";
133                 push @mirrors, "ftp://ftp.uu.net/archive/systems/gnu/$1";
134                 push @mirrors, "ftp://ftp.eu.uu.net/pub/gnu/$1";
135                 push @mirrors, "ftp://ftp.leo.org/pub/comp/os/unix/gnu/$1";
136                 push @mirrors, "ftp://ftp.digex.net/pub/gnu/$1";
137         } elsif ($mirror =~ /^\@KERNEL\/(.+)$/) {
138                 my @extra = ( $1 );
139                 if ($filename =~ /linux-\d+\.\d+\.\d+-rc/) {
140                         push @extra, "$extra[0]/testing";
141                 } elsif ($filename =~ /linux-(\d+\.\d+\.\d+)/) {
142                         push @extra, "$extra[0]/longterm/v$1";
143                 }               
144                 foreach my $dir (@extra) {
145                         push @mirrors, "ftp://ftp.geo.kernel.org/pub/$dir";
146                         push @mirrors, "http://ftp.geo.kernel.org/pub/$dir";
147                         push @mirrors, "ftp://ftp.all.kernel.org/pub/$dir";
148                         push @mirrors, "http://ftp.all.kernel.org/pub/$dir";
149                         push @mirrors, "ftp://ftp.de.kernel.org/pub/$dir";
150                         push @mirrors, "http://ftp.de.kernel.org/pub/$dir";
151                         push @mirrors, "ftp://ftp.fr.kernel.org/pub/$dir";
152                         push @mirrors, "http://ftp.fr.kernel.org/pub/$dir";
153                 }
154     } elsif ($mirror =~ /^\@GNOME\/(.+)$/) {
155                 push @mirrors, "http://ftp.gnome.org/pub/GNOME/sources/$1";
156                 push @mirrors, "http://ftp.unina.it/pub/linux/GNOME/sources/$1";
157                 push @mirrors, "http://fr2.rpmfind.net/linux/gnome.org/sources/$1";
158                 push @mirrors, "ftp://ftp.dit.upm.es/pub/GNOME/sources/$1";
159                 push @mirrors, "ftp://ftp.no.gnome.org/pub/GNOME/sources/$1";
160                 push @mirrors, "http://ftp.acc.umu.se/pub/GNOME/sources/$1";
161                 push @mirrors, "http://ftp.belnet.be/mirror/ftp.gnome.org/sources/$1";
162                 push @mirrors, "http://linorg.usp.br/gnome/sources/$1";
163                 push @mirrors, "http://mirror.aarnet.edu.au/pub/GNOME/sources/$1";
164                 push @mirrors, "http://mirrors.ibiblio.org/pub/mirrors/gnome/sources/$1";
165                 push @mirrors, "ftp://ftp.cse.buffalo.edu/pub/Gnome/sources/$1";
166                 push @mirrors, "ftp://ftp.nara.wide.ad.jp/pub/X11/GNOME/sources/$1";
167     }
168     else {
169                 push @mirrors, $mirror;
170         }
171 }
172
173 #push @mirrors, 'http://mirror1.openwrt.org';
174 push @mirrors, 'http://mirror2.openwrt.org/sources';
175 push @mirrors, 'http://downloads.openwrt.org/sources';
176
177 while (!$ok) {
178         my $mirror = shift @mirrors;
179         $mirror or die "No more mirrors to try - giving up.\n";
180
181         download($mirror);
182         -f "$target/$filename" and $ok = 1;
183 }
184
185 $SIG{INT} = \&cleanup;
186