add a menuconfig option for specifying a local download mirror
[openwrt.git] / scripts / download.pl
1 #!/usr/bin/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 my $target = shift @ARGV;
14 my $filename = shift @ARGV;
15 my $md5sum = shift @ARGV;
16 my $scriptdir = dirname($0);
17 my @mirrors;
18
19 my $ok;
20
21 @ARGV > 0 or die "Syntax: $0 <target dir> <filename> <md5sum> <mirror> [<mirror> ...]\n";
22
23 sub localmirrors {
24     my @mlist;
25     open LM, "$scriptdir/localmirrors" and do {
26             while (<LM>) {
27                         chomp $_;
28                         push @mlist, $_;
29                 }
30                 close LM;
31         };
32         open CONFIG, "<".$ENV{'TOPDIR'}."/.config" and do {
33                 while (<CONFIG>) {
34                         /^CONFIG_LOCALMIRROR="(.+)"/ and do {
35                                 chomp;
36                                 push @mlist, $1;
37                         };
38                 }
39                 close CONFIG;
40         };
41         
42
43     return @mlist;
44 }
45
46 sub which($) {
47         my $prog = shift;
48         my $res = `which $prog`;
49         $res or return undef;
50         $res =~ /^no / and return undef;
51         $res =~ /not found/ and return undef;
52         return $res;
53 }
54
55 my $md5cmd = which("md5sum");
56 $md5cmd or $md5cmd = which("md5");
57 $md5cmd or die 'no md5 checksum program found, please install md5 or md5sum';
58 chomp $md5cmd;
59
60 sub download
61 {
62         my $mirror = shift;
63         my $options = $ENV{WGET_OPTIONS};
64         $options or $options = "";
65         
66         $mirror =~ s/\/$//;
67         open WGET, "wget -t1 --timeout=20 $options -O- \"$mirror/$filename\" |" or die "Cannot launch wget.\n";
68         open MD5SUM, "| $md5cmd > \"$target/$filename.md5sum\"" or die "Cannot launch md5sum.\n";
69         open OUTPUT, "> $target/$filename.dl" or die "Cannot create file $target/$filename.dl: $!\n";
70         my $buffer;
71         while (read WGET, $buffer, 1048576) {
72                 print MD5SUM $buffer;
73                 print OUTPUT $buffer;
74         }
75         close MD5SUM;
76         close WGET;
77         close OUTPUT;
78         
79         if (($? >> 8) != 0 ) {
80                 print STDERR "Download failed.\n";
81                 cleanup();
82                 return;
83         }
84         
85         my $sum = `cat "$target/$filename.md5sum"`;
86         $sum =~ /^(\w+)\s*/ or die "Could not generate md5sum\n";
87         $sum = $1;
88         
89         if (($md5sum =~ /\w{32}/) and ($sum ne $md5sum)) {
90                 print STDERR "MD5 sum of the downloaded file does not match - deleting download.\n";
91                 cleanup();
92                 return;
93         }
94         
95         unlink "$target/$filename";
96         system("mv \"$target/$filename.dl\" \"$target/$filename\"");
97         cleanup();
98 }
99
100 sub cleanup
101 {
102         unlink "$target/$filename.dl";
103         unlink "$target/$filename.md5sum";
104 }
105
106 @mirrors = localmirrors();
107
108 foreach my $mirror (@ARGV) {
109         if ($mirror =~ /^\@SF\/(.+)$/) {
110                 # give sourceforge a few more tries, because it redirects to different mirrors
111                 for (1 .. 5) {
112                         push @mirrors, "http://downloads.sourceforge.net/$1";
113                 }
114         } elsif ($mirror =~ /^\@GNU\/(.+)$/) {
115                 my $gnupath = $1;
116                 push @mirrors, "ftp://ftp.gnu.org/gnu/$gnupath";
117                 push @mirrors, "ftp://ftp.belnet.be/mirror/ftp.gnu.org/gnu/$gnupath";
118                 push @mirrors, "ftp://ftp.mirror.nl/pub/mirror/gnu/$gnupath";
119                 push @mirrors, "http://mirror.switch.ch/ftp/mirror/gnu/$gnupath";
120                 push @mirrors, "ftp://ftp.uu.net/archive/systems/gnu/$gnupath";
121                 push @mirrors, "ftp://ftp.eu.uu.net/pub/gnu/$gnupath";
122                 push @mirrors, "ftp://ftp.leo.org/pub/comp/os/unix/gnu/$gnupath";
123                 push @mirrors, "ftp://ftp.digex.net/pub/gnu/$gnupath";
124         } else {
125                 push @mirrors, $mirror;
126         }
127 }
128
129 #push @mirrors, 'http://mirror1.openwrt.org';
130 push @mirrors, 'http://mirror2.openwrt.org/sources';
131 push @mirrors, 'http://downloads.openwrt.org/sources';
132
133 while (!$ok) {
134         my $mirror = shift @mirrors;
135         $mirror or die "No more mirrors to try - giving up.\n";
136         
137         download($mirror);
138         -f "$target/$filename" and $ok = 1;
139 }
140
141 $SIG{INT} = \&cleanup;
142