OpenWrt – Blame information for rev 2
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | #!/usr/bin/env perl |
2 | # |
||
3 | # Copyright (C) 2006 OpenWrt.org |
||
4 | # Copyright (C) 2016 LEDE project |
||
5 | # |
||
6 | # This is free software, licensed under the GNU General Public License v2. |
||
7 | # See /LICENSE for more information. |
||
8 | # |
||
9 | |||
10 | use strict; |
||
11 | use warnings; |
||
12 | use File::Basename; |
||
13 | use File::Copy; |
||
14 | use Text::ParseWords; |
||
15 | |||
16 | @ARGV > 2 or die "Syntax: $0 <target dir> <filename> <hash> <url filename> [<mirror> ...]\n"; |
||
17 | |||
18 | my $url_filename; |
||
19 | my $target = glob(shift @ARGV); |
||
20 | my $filename = shift @ARGV; |
||
21 | my $file_hash = shift @ARGV; |
||
22 | $url_filename = shift @ARGV unless $ARGV[0] =~ /:\/\//; |
||
23 | my $scriptdir = dirname($0); |
||
24 | my @mirrors; |
||
25 | my $ok; |
||
26 | |||
27 | $url_filename or $url_filename = $filename; |
||
28 | |||
29 | sub localmirrors { |
||
30 | my @mlist; |
||
31 | open LM, "$scriptdir/localmirrors" and do { |
||
32 | while (<LM>) { |
||
33 | chomp $_; |
||
34 | push @mlist, $_ if $_; |
||
35 | } |
||
36 | close LM; |
||
37 | }; |
||
38 | open CONFIG, "<".$ENV{'TOPDIR'}."/.config" and do { |
||
39 | while (<CONFIG>) { |
||
40 | /^CONFIG_LOCALMIRROR="(.+)"/ and do { |
||
41 | chomp; |
||
42 | my @local_mirrors = split(/;/, $1); |
||
43 | push @mlist, @local_mirrors; |
||
44 | }; |
||
45 | } |
||
46 | close CONFIG; |
||
47 | }; |
||
48 | |||
49 | my $mirror = $ENV{'DOWNLOAD_MIRROR'}; |
||
50 | $mirror and push @mlist, split(/;/, $mirror); |
||
51 | |||
52 | return @mlist; |
||
53 | } |
||
54 | |||
55 | sub which($) { |
||
56 | my $prog = shift; |
||
57 | my $res = `which $prog`; |
||
58 | $res or return undef; |
||
59 | $res =~ /^no / and return undef; |
||
60 | $res =~ /not found/ and return undef; |
||
61 | return $res; |
||
62 | } |
||
63 | |||
64 | sub hash_cmd() { |
||
65 | my $len = length($file_hash); |
||
66 | my $cmd; |
||
67 | |||
68 | $len == 64 and return "mkhash sha256"; |
||
69 | $len == 32 and return "mkhash md5"; |
||
70 | return undef; |
||
71 | } |
||
72 | |||
73 | sub download_cmd($) { |
||
74 | my $url = shift; |
||
75 | my $have_curl = 0; |
||
76 | |||
77 | if (open CURL, '-|', 'curl', '--version') { |
||
78 | if (defined(my $line = readline CURL)) { |
||
79 | $have_curl = 1 if $line =~ /^curl /; |
||
80 | } |
||
81 | close CURL; |
||
82 | } |
||
83 | |||
84 | return $have_curl |
||
85 | ? (qw(curl -f --connect-timeout 20 --retry 5 --location --insecure), shellwords($ENV{CURL_OPTIONS} || ''), $url) |
||
86 | : (qw(wget --tries=5 --timeout=20 --no-check-certificate --output-document=-), shellwords($ENV{WGET_OPTIONS} || ''), $url) |
||
87 | ; |
||
88 | } |
||
89 | |||
90 | my $hash_cmd = hash_cmd(); |
||
91 | $hash_cmd or ($file_hash eq "skip") or die "Cannot find appropriate hash command, ensure the provided hash is either a MD5 or SHA256 checksum.\n"; |
||
92 | |||
93 | sub download |
||
94 | { |
||
95 | my $mirror = shift; |
||
96 | |||
97 | $mirror =~ s!/$!!; |
||
98 | |||
99 | if ($mirror =~ s!^file://!!) { |
||
100 | if (! -d "$mirror") { |
||
101 | print STDERR "Wrong local cache directory -$mirror-.\n"; |
||
102 | cleanup(); |
||
103 | return; |
||
104 | } |
||
105 | |||
106 | if (! -d "$target") { |
||
107 | system("mkdir", "-p", "$target/"); |
||
108 | } |
||
109 | |||
110 | if (! open TMPDLS, "find $mirror -follow -name $filename 2>/dev/null |") { |
||
111 | print("Failed to search for $filename in $mirror\n"); |
||
112 | return; |
||
113 | } |
||
114 | |||
115 | my $link; |
||
116 | |||
117 | while (defined(my $line = readline TMPDLS)) { |
||
118 | chomp ($link = $line); |
||
119 | if ($. > 1) { |
||
120 | print("$. or more instances of $filename in $mirror found . Only one instance allowed.\n"); |
||
121 | return; |
||
122 | } |
||
123 | } |
||
124 | |||
125 | close TMPDLS; |
||
126 | |||
127 | if (! $link) { |
||
128 | print("No instances of $filename found in $mirror.\n"); |
||
129 | return; |
||
130 | } |
||
131 | |||
132 | print("Copying $filename from $link\n"); |
||
133 | copy($link, "$target/$filename.dl"); |
||
134 | |||
135 | $hash_cmd and do { |
||
136 | if (system("cat '$target/$filename.dl' | $hash_cmd > '$target/$filename.hash'")) { |
||
137 | print("Failed to generate hash for $filename\n"); |
||
138 | return; |
||
139 | } |
||
140 | }; |
||
141 | } else { |
||
142 | my @cmd = download_cmd("$mirror/$url_filename"); |
||
143 | print STDERR "+ ".join(" ",@cmd)."\n"; |
||
144 | open(FETCH_FD, '-|', @cmd) or die "Cannot launch curl or wget.\n"; |
||
145 | $hash_cmd and do { |
||
146 | open MD5SUM, "| $hash_cmd > '$target/$filename.hash'" or die "Cannot launch $hash_cmd.\n"; |
||
147 | }; |
||
148 | open OUTPUT, "> $target/$filename.dl" or die "Cannot create file $target/$filename.dl: $!\n"; |
||
149 | my $buffer; |
||
150 | while (read FETCH_FD, $buffer, 1048576) { |
||
151 | $hash_cmd and print MD5SUM $buffer; |
||
152 | print OUTPUT $buffer; |
||
153 | } |
||
154 | $hash_cmd and close MD5SUM; |
||
155 | close FETCH_FD; |
||
156 | close OUTPUT; |
||
157 | |||
158 | if ($? >> 8) { |
||
159 | print STDERR "Download failed.\n"; |
||
160 | cleanup(); |
||
161 | return; |
||
162 | } |
||
163 | } |
||
164 | |||
165 | $hash_cmd and do { |
||
166 | my $sum = `cat "$target/$filename.hash"`; |
||
167 | $sum =~ /^(\w+)\s*/ or die "Could not generate file hash\n"; |
||
168 | $sum = $1; |
||
169 | |||
170 | if ($sum ne $file_hash) { |
||
171 | print STDERR "Hash of the downloaded file does not match (file: $sum, requested: $file_hash) - deleting download.\n"; |
||
172 | cleanup(); |
||
173 | return; |
||
174 | } |
||
175 | }; |
||
176 | |||
177 | unlink "$target/$filename"; |
||
178 | system("mv", "$target/$filename.dl", "$target/$filename"); |
||
179 | cleanup(); |
||
180 | } |
||
181 | |||
182 | sub cleanup |
||
183 | { |
||
184 | unlink "$target/$filename.dl"; |
||
185 | unlink "$target/$filename.hash"; |
||
186 | } |
||
187 | |||
188 | @mirrors = localmirrors(); |
||
189 | |||
190 | foreach my $mirror (@ARGV) { |
||
191 | if ($mirror =~ /^\@SF\/(.+)$/) { |
||
192 | # give sourceforge a few more tries, because it redirects to different mirrors |
||
193 | for (1 .. 5) { |
||
194 | push @mirrors, "https://downloads.sourceforge.net/$1"; |
||
195 | } |
||
196 | } elsif ($mirror =~ /^\@APACHE\/(.+)$/) { |
||
197 | push @mirrors, "https://mirror.netcologne.de/apache.org/$1"; |
||
198 | push @mirrors, "https://mirror.aarnet.edu.au/pub/apache/$1"; |
||
199 | push @mirrors, "https://mirror.csclub.uwaterloo.ca/apache/$1"; |
||
200 | push @mirrors, "http://mirror.cogentco.com/pub/apache/$1"; |
||
201 | push @mirrors, "http://mirror.navercorp.com/apache/$1"; |
||
202 | push @mirrors, "http://ftp.jaist.ac.jp/pub/apache/$1"; |
||
203 | push @mirrors, "ftp://apache.cs.utah.edu/apache.org/$1"; |
||
204 | push @mirrors, "ftp://apache.mirrors.ovh.net/ftp.apache.org/dist/$1"; |
||
205 | } elsif ($mirror =~ /^\@GITHUB\/(.+)$/) { |
||
206 | # give github a few more tries (different mirrors) |
||
207 | for (1 .. 5) { |
||
208 | push @mirrors, "https://raw.githubusercontent.com/$1"; |
||
209 | } |
||
210 | } elsif ($mirror =~ /^\@GNU\/(.+)$/) { |
||
211 | push @mirrors, "https://mirror.csclub.uwaterloo.ca/gnu/$1"; |
||
212 | push @mirrors, "https://mirror.netcologne.de/gnu/$1"; |
||
213 | push @mirrors, "http://ftp.kddilabs.jp/GNU/gnu/$1"; |
||
214 | push @mirrors, "http://www.nic.funet.fi/pub/gnu/gnu/$1"; |
||
215 | push @mirrors, "http://mirror.internode.on.net/pub/gnu/$1"; |
||
216 | push @mirrors, "http://mirror.navercorp.com/gnu/$1"; |
||
217 | push @mirrors, "ftp://mirrors.rit.edu/gnu/$1"; |
||
218 | push @mirrors, "ftp://download.xs4all.nl/pub/gnu/"; |
||
219 | } elsif ($mirror =~ /^\@SAVANNAH\/(.+)$/) { |
||
220 | push @mirrors, "https://mirror.netcologne.de/savannah/$1"; |
||
221 | push @mirrors, "https://mirror.csclub.uwaterloo.ca/nongnu/$1"; |
||
222 | push @mirrors, "http://ftp.acc.umu.se/mirror/gnu.org/savannah/$1"; |
||
223 | push @mirrors, "http://nongnu.uib.no/$1"; |
||
224 | push @mirrors, "http://ftp.igh.cnrs.fr/pub/nongnu/$1"; |
||
225 | push @mirrors, "http://public.p-knowledge.co.jp/Savannah-nongnu-mirror/$1"; |
||
226 | push @mirrors, "ftp://cdimage.debian.org/mirror/gnu.org/savannah/$1"; |
||
227 | push @mirrors, "ftp://ftp.acc.umu.se/mirror/gnu.org/savannah/$1"; |
||
228 | } elsif ($mirror =~ /^\@KERNEL\/(.+)$/) { |
||
229 | my @extra = ( $1 ); |
||
230 | if ($filename =~ /linux-\d+\.\d+(?:\.\d+)?-rc/) { |
||
231 | push @extra, "$extra[0]/testing"; |
||
232 | } elsif ($filename =~ /linux-(\d+\.\d+(?:\.\d+)?)/) { |
||
233 | push @extra, "$extra[0]/longterm/v$1"; |
||
234 | } |
||
235 | foreach my $dir (@extra) { |
||
236 | push @mirrors, "https://cdn.kernel.org/pub/$dir"; |
||
237 | push @mirrors, "https://mirror.rackspace.com/kernel.org/$dir"; |
||
238 | push @mirrors, "http://download.xs4all.nl/ftp.kernel.org/pub/$dir"; |
||
239 | push @mirrors, "http://mirrors.mit.edu/kernel/$dir"; |
||
240 | push @mirrors, "http://ftp.nara.wide.ad.jp/pub/kernel.org/$dir"; |
||
241 | push @mirrors, "http://www.ring.gr.jp/archives/linux/kernel.org/$dir"; |
||
242 | push @mirrors, "ftp://ftp.riken.jp/Linux/kernel.org/$dir"; |
||
243 | push @mirrors, "ftp://www.mirrorservice.org/sites/ftp.kernel.org/pub/$dir"; |
||
244 | } |
||
245 | } elsif ($mirror =~ /^\@GNOME\/(.+)$/) { |
||
246 | push @mirrors, "https://mirror.csclub.uwaterloo.ca/gnome/sources/$1"; |
||
247 | push @mirrors, "http://ftp.acc.umu.se/pub/GNOME/sources/$1"; |
||
248 | push @mirrors, "http://ftp.kaist.ac.kr/gnome/sources/$1"; |
||
249 | push @mirrors, "http://www.mirrorservice.org/sites/ftp.gnome.org/pub/GNOME/sources/$1"; |
||
250 | push @mirrors, "http://mirror.internode.on.net/pub/gnome/sources/$1"; |
||
251 | push @mirrors, "http://ftp.belnet.be/ftp.gnome.org/sources/$1"; |
||
252 | push @mirrors, "ftp://ftp.cse.buffalo.edu/pub/Gnome/sources/$1"; |
||
253 | push @mirrors, "ftp://ftp.nara.wide.ad.jp/pub/X11/GNOME/sources/$1"; |
||
254 | } |
||
255 | else { |
||
256 | push @mirrors, $mirror; |
||
257 | } |
||
258 | } |
||
259 | |||
260 | #push @mirrors, 'https://mirror1.openwrt.org'; |
||
261 | push @mirrors, 'https://sources.lede-project.org'; |
||
262 | push @mirrors, 'https://mirror2.openwrt.org/sources'; |
||
263 | push @mirrors, 'https://downloads.openwrt.org/sources'; |
||
264 | |||
265 | while (!-f "$target/$filename") { |
||
266 | my $mirror = shift @mirrors; |
||
267 | $mirror or die "No more mirrors to try - giving up.\n"; |
||
268 | |||
269 | download($mirror); |
||
270 | } |
||
271 | |||
272 | $SIG{INT} = \&cleanup; |
||
273 |