gnu: Add guile2.2-haunt.
[jackhill/guix/guix.git] / guix / download.scm
CommitLineData
233e7676 1;;; GNU Guix --- Functional package management for GNU
95001d4b 2;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
9884d7ec 3;;; Copyright © 2013, 2014, 2015 Andreas Enge <andreas@enge.fr>
95001d4b 4;;; Copyright © 2015 Federico Beffa <beffa@fbengineering.ch>
fe224d20 5;;; Copyright © 2016 Alex Griffin <a@ajgrf.com>
9c97afe8 6;;; Copyright © 2016 David Craven <david@craven.ch>
58f91e4d 7;;; Copyright © 2017 Tobias Geerinckx-Rice <me@tobias.gr>
62cab99c 8;;;
233e7676 9;;; This file is part of GNU Guix.
62cab99c 10;;;
233e7676 11;;; GNU Guix is free software; you can redistribute it and/or modify it
62cab99c
LC
12;;; under the terms of the GNU General Public License as published by
13;;; the Free Software Foundation; either version 3 of the License, or (at
14;;; your option) any later version.
15;;;
233e7676 16;;; GNU Guix is distributed in the hope that it will be useful, but
62cab99c
LC
17;;; WITHOUT ANY WARRANTY; without even the implied warranty of
18;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;;; GNU General Public License for more details.
20;;;
21;;; You should have received a copy of the GNU General Public License
233e7676 22;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
62cab99c
LC
23
24(define-module (guix download)
25 #:use-module (ice-9 match)
26 #:use-module (guix derivations)
27 #:use-module (guix packages)
e87f0591 28 #:use-module (guix store)
b5b73a82 29 #:use-module ((guix build download) #:prefix build:)
6f8f8ccb
LC
30 #:use-module (guix monads)
31 #:use-module (guix gexp)
62cab99c 32 #:use-module (guix utils)
d8907ac4 33 #:use-module (web uri)
483f1158 34 #:use-module (srfi srfi-1)
94d222ad 35 #:use-module (srfi srfi-26)
ec4d308a 36 #:export (%mirrors
861693f3 37 url-fetch
95001d4b 38 url-fetch/tarbomb
814b099a 39 url-fetch/zipbomb
861693f3 40 download-to-store))
62cab99c
LC
41
42;;; Commentary:
43;;;
44;;; Produce fixed-output derivations with data fetched over HTTP or FTP.
45;;;
46;;; Code:
47
94d222ad
LC
48(define %mirrors
49 ;; Mirror lists used when `mirror://' URLs are passed.
50 (let* ((gnu-mirrors
51 '(;; This one redirects to a (supposedly) nearby and (supposedly)
52 ;; up-to-date mirror.
53 "http://ftpmirror.gnu.org/"
54
55 "ftp://ftp.cs.tu-berlin.de/pub/gnu/"
94d222ad
LC
56 "ftp://ftp.funet.fi/pub/mirrors/ftp.gnu.org/gnu/"
57
58 ;; This one is the master repository, and thus it's always
59 ;; up-to-date.
60 "http://ftp.gnu.org/pub/gnu/")))
61 `((gnu ,@gnu-mirrors)
62 (gcc
63 "ftp://ftp.nluug.nl/mirror/languages/gcc/"
64 "ftp://ftp.fu-berlin.de/unix/languages/gcc/"
65 "ftp://ftp.irisa.fr/pub/mirrors/gcc.gnu.org/gcc/"
66 "ftp://gcc.gnu.org/pub/gcc/"
67 ,@(map (cut string-append <> "/gcc") gnu-mirrors))
68 (gnupg
69 "ftp://gd.tuwien.ac.at/privacy/gnupg/"
d57b88be 70 "ftp://mirrors.dotsrc.org/gcrypt/"
94d222ad 71 "ftp://mirror.cict.fr/gnupg/"
d57b88be
AE
72 "http://artfiles.org/gnupg.org"
73 "ftp://ftp.franken.de/pub/crypt/mirror/ftp.gnupg.org/gcrypt/"
74 "ftp://ftp.freenet.de/pub/ftp.gnupg.org/gcrypt/"
75 "http://www.crysys.hu/"
76 "ftp://ftp.hi.is/pub/mirrors/gnupg/"
77 "ftp://ftp.heanet.ie/mirrors/ftp.gnupg.org/gcrypt/"
78 "ftp://ftp.bit.nl/mirror/gnupg/"
79 "ftp://ftp.surfnet.nl/pub/security/gnupg/"
80 "ftp://ftp.iasi.roedu.net/pub/mirrors/ftp.gnupg.org/"
81 "ftp://ftp.sunet.se/pub/security/gnupg/"
82 "ftp://mirror.switch.ch/mirror/gnupg/"
83 "ftp://mirror.tje.me.uk/pub/mirrors/ftp.gnupg.org/"
84 "ftp://ftp.mirrorservice.org/sites/ftp.gnupg.org/gcrypt/"
85 "ftp://ftp.ring.gr.jp/pub/net/gnupg/"
86 "ftp://ftp.gnupg.org/gcrypt/")
71eb5c10
LC
87 (gnome
88 "http://ftp.belnet.be/ftp.gnome.org/"
89 "http://ftp.linux.org.uk/mirrors/ftp.gnome.org/"
90 "http://ftp.gnome.org/pub/GNOME/"
93897a45 91 "https://download.gnome.org/"
71eb5c10 92 "http://mirror.yandex.ru/mirrors/ftp.gnome.org/")
442c2c99 93 (hackage
4c13aad0 94 "http://hackage.haskell.org/")
94d222ad 95 (savannah
a4eabecd 96 "http://download.savannah.gnu.org/releases/"
94d222ad
LC
97 "ftp://ftp.twaren.net/Unix/NonGNU/"
98 "ftp://mirror.csclub.uwaterloo.ca/nongnu/"
99 "ftp://mirror.publicns.net/pub/nongnu/"
100 "ftp://savannah.c3sl.ufpr.br/"
101 "http://ftp.cc.uoc.gr/mirrors/nongnu.org/"
102 "http://ftp.twaren.net/Unix/NonGNU/"
103 "http://mirror.csclub.uwaterloo.ca/nongnu/"
104 "http://nongnu.askapache.com/"
105 "http://savannah.c3sl.ufpr.br/"
3bba7b0a
LC
106 "http://www.centervenus.com/mirrors/nongnu/"
107 "http://download.savannah.gnu.org/releases-noredirect/")
321dc4df 108 (sourceforge ; https://sourceforge.net/p/forge/documentation/Mirrors/
fe224d20 109 "http://downloads.sourceforge.net/project/"
cd4c41fd
LC
110 "http://ufpr.dl.sourceforge.net/project/"
111 "http://heanet.dl.sourceforge.net/project/"
112 "http://freefr.dl.sourceforge.net/project/"
113 "http://internode.dl.sourceforge.net/project/"
114 "http://jaist.dl.sourceforge.net/project/"
115 "http://kent.dl.sourceforge.net/project/"
116 "http://liquidtelecom.dl.sourceforge.net/project/"
117 "http://nbtelecom.dl.sourceforge.net/project/"
118 "http://nchc.dl.sourceforge.net/project/"
119 "http://ncu.dl.sourceforge.net/project/"
120 "http://netcologne.dl.sourceforge.net/project/"
121 "http://netix.dl.sourceforge.net/project/"
122 "http://pilotfiber.dl.sourceforge.net/project/"
123 "http://superb-sea2.dl.sourceforge.net/project/"
124 "http://tenet.dl.sourceforge.net/project/"
125 "http://vorboss.dl.sourceforge.net/project/"
126 "http://netassist.dl.sourceforge.net/project/")
b40b259f
LC
127 (kernel.org
128 "http://www.all.kernel.org/pub/"
129 "http://ramses.wh2.tu-dresden.de/pub/mirrors/kernel.org/"
130 "http://linux-kernel.uio.no/pub/"
131 "http://kernel.osuosl.org/pub/"
5d9cd707
LC
132 "ftp://ftp.funet.fi/pub/mirrors/ftp.kernel.org/pub/"
133 "http://ftp.be.debian.org/pub/"
134 "http://mirror.linux.org.au/")
47f9db41
LC
135 (apache ; from http://www.apache.org/mirrors/dist.html
136 "http://www.eu.apache.org/dist/"
137 "http://www.us.apache.org/dist/"
138 "ftp://gd.tuwien.ac.at/pub/infosys/servers/http/apache/dist/"
139 "http://apache.belnet.be/"
140 "http://mirrors.ircam.fr/pub/apache/"
f06afd4d
LC
141 "http://apache-mirror.rbc.ru/pub/apache/"
142
143 ;; As a last resort, try the archive.
144 "http://archive.apache.org/dist/")
149acc29 145 (xorg ; from http://www.x.org/wiki/Releases/Download
0820a58b 146 "http://www.x.org/releases/" ; main mirrors
149acc29
AE
147 "ftp://mirror.csclub.uwaterloo.ca/x.org/" ; North America
148 "ftp://xorg.mirrors.pair.com/"
149 "http://mirror.csclub.uwaterloo.ca/x.org/"
150 "http://xorg.mirrors.pair.com/"
151 "http://mirror.us.leaseweb.net/xorg/"
152 "ftp://artfiles.org/x.org/" ; Europe
153 "ftp://ftp.chg.ru/pub/X11/x.org/"
154 "ftp://ftp.fu-berlin.de/unix/X11/FTP.X.ORG/"
155 "ftp://ftp.gwdg.de/pub/x11/x.org/"
156 "ftp://ftp.mirrorservice.org/sites/ftp.x.org/"
157 "ftp://ftp.ntua.gr/pub/X11/"
158 "ftp://ftp.piotrkosoft.net/pub/mirrors/ftp.x.org/"
159 "ftp://ftp.portal-to-web.de/pub/mirrors/x.org/"
160 "ftp://ftp.solnet.ch/mirror/x.org/"
149acc29
AE
161 "ftp://gd.tuwien.ac.at/X11/"
162 "ftp://mi.mirror.garr.it/mirrors/x.org/"
163 "ftp://mirror.cict.fr/x.org/"
164 "ftp://mirror.switch.ch/mirror/X11/"
165 "ftp://mirrors.ircam.fr/pub/x.org/"
166 "ftp://x.mirrors.skynet.be/pub/ftp.x.org/"
167 "ftp://ftp.cs.cuhk.edu.hk/pub/X11" ; East Asia
168 "ftp://ftp.u-aizu.ac.jp/pub/x11/x.org/"
169 "ftp://ftp.yz.yamagata-u.ac.jp/pub/X11/x.org/"
170 "ftp://ftp.kaist.ac.kr/x.org/"
171 "ftp://mirrors.go-part.com/xorg/"
172 "http://x.cs.pu.edu.tw/"
6af31019
LC
173 "ftp://ftp.is.co.za/pub/x.org") ; South Africa
174 (cpan ; from http://www.cpan.org/SITES.html
8aa5e15e 175 "http://mirror.ibcp.fr/pub/CPAN/"
6af31019
LC
176 "ftp://ftp.ciril.fr/pub/cpan/"
177 "ftp://artfiles.org/cpan.org/"
178 "http://www.cpan.org/"
179 "ftp://cpan.rinet.ru/pub/mirror/CPAN/"
6af31019
LC
180 "ftp://cpan.inode.at/"
181 "ftp://cpan.iht.co.il/"
182 "ftp://ftp.osuosl.org/pub/CPAN/"
183 "ftp://ftp.nara.wide.ad.jp/pub/CPAN/"
184 "http://mirrors.163.com/cpan/"
552ffa02
EF
185 "ftp://cpan.mirror.ac.za/"
186 "http://cpan.mirrors.ionfish.org/"
187 "http://cpan.mirror.dkm.cz/pub/CPAN/"
188 "http://cpan.mirror.iphh.net/"
189 "http://mirrors.teentelecom.net/CPAN/"
190 "http://mirror.teklinks.com/CPAN/"
191 "http://cpan.weepeetelecom.be/"
192 "http://mirrors.xservers.ro/CPAN/"
193 "http://cpan.yimg.com/"
194 "http://mirror.yazd.ac.ir/cpan/"
195 "http://ftp.belnet.be/ftp.cpan.org/")
cb7e4867
RW
196 (cran
197 ;; Arbitrary mirrors from http://cran.r-project.org/mirrors.html
198 ;; This one automatically redirects to servers worldwide
c009bb5a 199 "http://cran.r-project.org/"
cb7e4867
RW
200 "http://cran.rstudio.com/"
201 "http://cran.univ-lyon1.fr/"
cb7e4867
RW
202 "http://cran.ism.ac.jp/"
203 "http://cran.stat.auckland.ac.nz/"
204 "http://cran.mirror.ac.za/"
205 "http://cran.csie.ntu.edu.tw/")
6d763bdd
AE
206 (imagemagick
207 ;; from http://www.imagemagick.org/script/download.php
208 ;; (without mirrors that are unavailable or not up to date)
209 ;; mirrors keeping old versions at the top level
6d763bdd
AE
210 "ftp://sunsite.icm.edu.pl/packages/ImageMagick/"
211 ;; mirrors moving old versions to "legacy"
212 "http://mirrors-au.go-parts.com/mirrors/ImageMagick/"
213 "ftp://mirror.aarnet.edu.au/pub/imagemagick/"
7fa37abc 214 "http://mirror.checkdomain.de/imagemagick/"
6d763bdd
AE
215 "ftp://ftp.kddlabs.co.jp/graphics/ImageMagick/"
216 "ftp://ftp.u-aizu.ac.jp/pub/graphics/image/ImageMagick/imagemagick.org/"
217 "ftp://ftp.nluug.nl/pub/ImageMagick/"
218 "http://ftp.surfnet.nl/pub/ImageMagick/"
219 "http://mirror.searchdaimon.com/ImageMagick"
220 "ftp://ftp.tpnet.pl/pub/graphics/ImageMagick/"
221 "http://mirrors-ru.go-parts.com/mirrors/ImageMagick/"
7fa37abc 222 "http://mirror.is.co.za/pub/imagemagick/"
6d763bdd
AE
223 "http://mirrors-uk.go-parts.com/mirrors/ImageMagick/"
224 "http://mirrors-usa.go-parts.com/mirrors/ImageMagick/"
225 "ftp://ftp.fifi.org/pub/ImageMagick/"
226 "http://www.imagemagick.org/download/"
227 ;; one legacy location as a last resort
228 "http://www.imagemagick.org/download/legacy/")
e0029b74
LC
229 (debian
230 "http://ftp.de.debian.org/debian/"
231 "http://ftp.fr.debian.org/debian/"
6b287c5c 232 "http://ftp.debian.org/debian/"
ff02b826
DC
233 "http://archive.debian.org/debian/")
234 (kde
112f089d 235 "http://download.kde.org"
ff02b826
DC
236 ;; Mirrors from http://files.kde.org/extra/mirrors.html
237 ;; Europe
238 "http://mirror.easyname.at/kde"
239 "http://mirror.karneval.cz/pub/kde"
240 "http://ftp.fi.muni.cz/pub/kde/"
241 "http://mirror.oss.maxcdn.com/kde/"
242 "http://ftp5.gwdg.de/pub/linux/kde/"
243 "http://ftp-stud.fht-esslingen.de/Mirrors/ftp.kde.org/pub/kde/"
244 "http://mirror.klaus-uwe.me/kde/ftp/"
245 "http://kde.beta.mirror.ga/"
246 "http://kde.alpha.mirror.ga/"
247 "http://mirror.netcologne.de/kde"
248 "http://vesta.informatik.rwth-aachen.de/ftp/pub/mirror/kde/"
249 "http://ftp.rz.uni-wuerzburg.de/pub/unix/kde/"
250 "http://mirrors.dotsrc.org/kde/"
251 "http://ftp.funet.fi/pub/mirrors/ftp.kde.org/pub/kde/"
252 "http://kde-mirror.freenux.org/"
253 "http://mirrors.ircam.fr/pub/KDE/"
254 "http://www-ftp.lip6.fr/pub/X11/kde/"
255 "http://fr2.rpmfind.net/linux/KDE/"
256 "http://kde.mirror.anlx.net/"
257 "http://www.mirrorservice.org/sites/ftp.kde.org/pub/kde/"
258 "http://ftp.heanet.ie/mirrors/ftp.kde.org/"
259 "http://ftp.nluug.nl/pub/windowing/kde/"
260 "http://ftp.surfnet.nl/windowing/kde/"
261 "http://ftp.icm.edu.pl/pub/unix/kde/"
262 "http://ftp.pbone.net/pub/kde/"
263 "http://piotrkosoft.net/pub/mirrors/ftp.kde.org/"
264 "http://mirrors.fe.up.pt/pub/kde/"
265 "http://ftp.iasi.roedu.net/pub/mirrors/ftp.kde.org/"
266 "http://ftp.acc.umu.se/mirror/kde.org/ftp/"
267 "http://kde.ip-connect.vn.ua/"
268 ;; North America
269 "http://mirror.its.dal.ca/kde/"
270 "http://mirror.csclub.uwaterloo.ca/kde/"
271 "http://mirror.cc.columbia.edu/pub/software/kde/"
272 "http://mirrors-usa.go-parts.com/kde"
273 "http://kde.mirrors.hoobly.com/"
274 "http://ftp.ussg.iu.edu/kde/"
275 "http://mirrors.mit.edu/kde/"
276 "http://kde.mirrors.tds.net/pub/kde/"
277 ;; Oceania
278 "http://ftp.kddlabs.co.jp/pub/X11/kde/"
279 "http://kde.mirror.uber.com.au/"))))
94d222ad 280
53216419
LC
281(define %mirror-file
282 ;; Copy of the list of mirrors to a file. This allows us to keep a single
283 ;; copy in the store, and computing it here avoids repeated calls to
284 ;; 'object->string'.
285 (plain-file "mirrors" (object->string %mirrors)))
286
cd436bf0
LC
287(define %content-addressed-mirrors
288 ;; List of content-addressed mirrors. Each mirror is represented as a
ab84b927
LC
289 ;; procedure that takes a file name, an algorithm (symbol) and a hash
290 ;; (bytevector), and returns a URL or #f.
40f788b9 291 ;; Note: Avoid 'https' to mitigate <http://bugs.gnu.org/22774>.
cd436bf0 292 ;; TODO: Add more.
ab84b927 293 '(list (lambda (file algo hash)
40f788b9
LC
294 ;; Files served by 'guix publish' are accessible under a single
295 ;; hash algorithm.
296 (string-append "http://mirror.hydra.gnu.org/file/"
297 file "/" (symbol->string algo) "/"
298 (bytevector->nix-base32-string hash)))
299 (lambda (file algo hash)
cd436bf0
LC
300 ;; 'tarballs.nixos.org' supports several algorithms.
301 (string-append "http://tarballs.nixos.org/"
302 (symbol->string algo) "/"
303 (bytevector->nix-base32-string hash)))))
304
305(define %content-addressed-mirror-file
306 ;; Content-addressed mirrors stored in a file.
307 (plain-file "content-addressed-mirrors"
308 (object->string %content-addressed-mirrors)))
309
6f8f8ccb 310(define (gnutls-package)
6119ebf1 311 "Return the default GnuTLS package."
9884d7ec 312 (let ((module (resolve-interface '(gnu packages tls))))
6f8f8ccb 313 (module-ref module 'gnutls)))
94d222ad 314
05ceb8dc
LC
315(define built-in-builders*
316 (let ((cache (make-weak-key-hash-table)))
317 (lambda ()
318 "Return, as a monadic value, the list of built-in builders supported by
319the daemon."
320 (lambda (store)
321 ;; Memoize the result to avoid repeated RPCs.
322 (values (or (hashq-ref cache store)
323 (let ((result (built-in-builders store)))
324 (hashq-set! cache store result)
325 result))
326 store)))))
94d222ad 327
05ceb8dc
LC
328(define* (built-in-download file-name url
329 #:key system hash-algo hash
330 mirrors content-addressed-mirrors
331 (guile 'unused))
332 "Download FILE-NAME from URL using the built-in 'download' builder.
62cab99c 333
05ceb8dc
LC
334This is an \"out-of-band\" download in that the returned derivation does not
335explicitly depend on Guile, GnuTLS, etc. Instead, the daemon performs the
336download by itself using its own dependencies."
337 (mlet %store-monad ((mirrors (lower-object mirrors))
338 (content-addressed-mirrors
339 (lower-object content-addressed-mirrors)))
340 (raw-derivation file-name "builtin:download" '()
341 #:system system
342 #:hash-algo hash-algo
343 #:hash hash
344 #:inputs `((,mirrors)
345 (,content-addressed-mirrors))
346
347 ;; Honor the user's proxy and locale settings.
348 #:leaked-env-vars '("http_proxy" "https_proxy"
349 "LC_ALL" "LC_MESSAGES" "LANG"
350 "COLUMNS")
351
352 #:env-vars `(("url" . ,(object->string url))
353 ("mirrors" . ,mirrors)
354 ("content-addressed-mirrors"
4c80d4c4
LC
355 . ,content-addressed-mirrors))
356
357 ;; Do not offload this derivation because we cannot be
358 ;; sure that the remote daemon supports the 'download'
359 ;; built-in. We may remove this limitation when support
360 ;; for that built-in is widespread.
361 #:local-build? #t)))
05ceb8dc
LC
362
363(define* (in-band-download file-name url
364 #:key system hash-algo hash
365 mirrors content-addressed-mirrors
366 guile)
367 "Download FILE-NAME from URL using a normal, \"in-band\" fixed-output
368derivation.
369
370This is now deprecated since it has the drawback of causing bootstrapping
371issues: we may need to build GnuTLS just to be able to download the source of
372GnuTLS itself and its dependencies. See <http://bugs.gnu.org/22774>."
483f1158
LC
373 (define need-gnutls?
374 ;; True if any of the URLs need TLS support.
375 (let ((https? (cut string-prefix? "https://" <>)))
376 (match url
377 ((? string?)
378 (https? url))
379 ((url ...)
380 (any https? url)))))
381
6f8f8ccb 382 (define builder
e9b046fd
LC
383 (with-imported-modules '((guix build download)
384 (guix build utils)
385 (guix ftp-client)
386 (guix base32)
387 (guix base64))
388 #~(begin
389 #+(if need-gnutls?
6f8f8ccb 390
e9b046fd
LC
391 ;; Add GnuTLS to the inputs and to the load path.
392 #~(eval-when (load expand eval)
393 (set! %load-path
394 (cons (string-append #+(gnutls-package)
395 "/share/guile/site/"
396 (effective-version))
397 %load-path)))
398 #~#t)
6f8f8ccb 399
e9b046fd
LC
400 (use-modules (guix build download)
401 (guix base32))
cd436bf0 402
e9b046fd
LC
403 (let ((value-from-environment (lambda (variable)
404 (call-with-input-string
405 (getenv variable)
406 read))))
407 (url-fetch (value-from-environment "guix download url")
408 #$output
05ceb8dc 409 #:mirrors (call-with-input-file #$mirrors read)
ced20032 410
e9b046fd
LC
411 ;; Content-addressed mirrors.
412 #:hashes
413 (value-from-environment "guix download hashes")
414 #:content-addressed-mirrors
05ceb8dc 415 (primitive-load #$content-addressed-mirrors)
bc3c41ce
LC
416
417 ;; No need to validate certificates since we know the
418 ;; hash of the expected result.
419 #:verify-certificate? #f)))))
6f8f8ccb 420
6c5b56f9 421 (mlet %store-monad ((guile (package->derivation guile system)))
05ceb8dc
LC
422 (gexp->derivation file-name builder
423 #:guile-for-build guile
424 #:system system
425 #:hash-algo hash-algo
426 #:hash hash
427
428 ;; Use environment variables and a fixed script
429 ;; name so there's only one script in store for
430 ;; all the downloads.
431 #:script-name "download"
432 #:env-vars
433 `(("guix download url" . ,(object->string url))
434 ("guix download hashes"
435 . ,(object->string `((,hash-algo . ,hash)))))
436
437 ;; Honor the user's proxy settings.
438 #:leaked-env-vars '("http_proxy" "https_proxy")
439
440 ;; In general, offloading downloads is not a good
441 ;; idea. Daemons before 0.8.3 would also
442 ;; interpret this as "do not substitute" (see
443 ;; <https://bugs.gnu.org/18747>.)
444 #:local-build? #t)))
445
446(define* (url-fetch url hash-algo hash
447 #:optional name
448 #:key (system (%current-system))
449 (guile (default-guile)))
450 "Return a fixed-output derivation that fetches URL (a string, or a list of
451strings denoting alternate URLs), which is expected to have hash HASH of type
452HASH-ALGO (a symbol). By default, the file name is the base name of URL;
453optionally, NAME can specify a different file name.
454
455When one of the URL starts with mirror://, then its host part is
456interpreted as the name of a mirror scheme, taken from %MIRROR-FILE.
457
458Alternately, when URL starts with file://, return the corresponding file name
459in the store."
460 (define file-name
461 (match url
462 ((head _ ...)
463 (basename head))
464 (_
465 (basename url))))
466
882383a9
LC
467 (let ((uri (and (string? url) (string->uri url))))
468 (if (or (and (string? url) (not uri))
469 (and uri (memq (uri-scheme uri) '(#f file))))
f220a838
LC
470 (interned-file (if uri (uri-path uri) url)
471 (or name file-name))
05ceb8dc
LC
472 (mlet* %store-monad ((builtins (built-in-builders*))
473 (download -> (if (member "download" builtins)
474 built-in-download
475 in-band-download)))
476 (download (or name file-name) url
477 #:guile guile
478 #:system system
479 #:hash-algo hash-algo
480 #:hash hash
481 #:mirrors %mirror-file
482 #:content-addressed-mirrors
483 %content-addressed-mirror-file)))))
62cab99c 484
95001d4b
LC
485(define* (url-fetch/tarbomb url hash-algo hash
486 #:optional name
487 #:key (system (%current-system))
488 (guile (default-guile)))
489 "Similar to 'url-fetch' but unpack the file from URL in a directory of its
490own. This helper makes it easier to deal with \"tar bombs\"."
58f91e4d
TGR
491 (define file-name
492 (match url
493 ((head _ ...)
494 (basename head))
495 (_
496 (basename url))))
95001d4b
LC
497 (define gzip
498 (module-ref (resolve-interface '(gnu packages compression)) 'gzip))
499 (define tar
500 (module-ref (resolve-interface '(gnu packages base)) 'tar))
501
502 (mlet %store-monad ((drv (url-fetch url hash-algo hash
58f91e4d
TGR
503 (string-append "tarbomb-"
504 (or name file-name))
95001d4b
LC
505 #:system system
506 #:guile guile)))
507 ;; Take the tar bomb, and simply unpack it as a directory.
58f91e4d 508 (gexp->derivation (or name file-name)
95001d4b
LC
509 #~(begin
510 (mkdir #$output)
511 (setenv "PATH" (string-append #$gzip "/bin"))
512 (chdir #$output)
513 (zero? (system* (string-append #$tar "/bin/tar")
514 "xf" #$drv)))
515 #:local-build? #t)))
516
814b099a
TGR
517(define* (url-fetch/zipbomb url hash-algo hash
518 #:optional name
519 #:key (system (%current-system))
520 (guile (default-guile)))
521 "Similar to 'url-fetch' but unpack the zip file at URL in a directory of its
522own. This helper makes it easier to deal with \"zip bombs\"."
523 (define file-name
524 (match url
525 ((head _ ...)
526 (basename head))
527 (_
528 (basename url))))
529 (define unzip
530 (module-ref (resolve-interface '(gnu packages zip)) 'unzip))
531
532 (mlet %store-monad ((drv (url-fetch url hash-algo hash
533 (string-append "zipbomb-"
534 (or name file-name))
535 #:system system
536 #:guile guile)))
537 ;; Take the zip bomb, and simply unpack it as a directory.
538 (gexp->derivation (or name file-name)
539 #~(begin
540 (mkdir #$output)
541 (chdir #$output)
542 (zero? (system* (string-append #$unzip "/bin/unzip")
543 #$drv)))
544 #:local-build? #t)))
545
861693f3 546(define* (download-to-store store url #:optional (name (basename url))
64b8695c
LC
547 #:key (log (current-error-port)) recursive?
548 (verify-certificate? #t))
861693f3 549 "Download from URL to STORE, either under NAME or URL's basename if
a43b55f1 550omitted. Write progress reports to LOG. RECURSIVE? has the same effect as
64b8695c
LC
551the same-named parameter of 'add-to-store'. VERIFY-CERTIFICATE? determines
552whether or not to validate HTTPS server certificates."
d8907ac4
LC
553 (define uri
554 (string->uri url))
555
d91a8791 556 (if (or (not uri) (memq (uri-scheme uri) '(file #f)))
a43b55f1 557 (add-to-store store name recursive? "sha256"
d91a8791 558 (if uri (uri-path uri) url))
d8907ac4
LC
559 (call-with-temporary-output-file
560 (lambda (temp port)
561 (let ((result
562 (parameterize ((current-output-port log))
64b8695c
LC
563 (build:url-fetch url temp
564 #:mirrors %mirrors
565 #:verify-certificate?
566 verify-certificate?))))
d8907ac4
LC
567 (close port)
568 (and result
a43b55f1 569 (add-to-store store name recursive? "sha256" temp)))))))
861693f3 570
62cab99c 571;;; download.scm ends here