summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeo Famulari <leo@famulari.name>2017-04-22 18:27:12 -0400
committerLeo Famulari <leo@famulari.name>2017-04-22 18:27:12 -0400
commit1524851f58d8d69f6c6e1c6406cf174083bbe82d (patch)
treed7c63b716501e4423e9f7173790a8cc4c3962935
parent0802f3a034815576bf0e28c59c968400566b418b (diff)
parented9fb46b16cf7632e6df15c52c7183807fe5d1f9 (diff)
downloadguix-1524851f58d8d69f6c6e1c6406cf174083bbe82d.tar.gz
Merge branch 'master' into staging
-rw-r--r--.dir-locals.el1
-rw-r--r--.mailmap13
-rw-r--r--Makefile.am7
-rw-r--r--doc/guix.texi181
-rw-r--r--gnu/local.mk38
-rw-r--r--gnu/packages/admin.scm18
-rw-r--r--gnu/packages/android.scm300
-rw-r--r--gnu/packages/audio.scm8
-rw-r--r--gnu/packages/autotools.scm31
-rw-r--r--gnu/packages/base.scm17
-rw-r--r--gnu/packages/bioinformatics.scm12
-rw-r--r--gnu/packages/build-tools.scm30
-rw-r--r--gnu/packages/certs.scm4
-rw-r--r--gnu/packages/crypto.scm4
-rw-r--r--gnu/packages/curl.scm14
-rw-r--r--gnu/packages/emacs.scm14
-rw-r--r--gnu/packages/fontutils.scm22
-rw-r--r--gnu/packages/freedesktop.scm50
-rw-r--r--gnu/packages/games.scm84
-rw-r--r--gnu/packages/gnome.scm25
-rw-r--r--gnu/packages/gnunet.scm6
-rw-r--r--gnu/packages/gnuzilla.scm281
-rw-r--r--gnu/packages/gstreamer.scm6
-rw-r--r--gnu/packages/guile.scm4
-rw-r--r--gnu/packages/hurd.scm48
-rw-r--r--gnu/packages/ibus.scm24
-rw-r--r--gnu/packages/icu4c.scm3
-rw-r--r--gnu/packages/image-viewers.scm42
-rw-r--r--gnu/packages/image.scm4
-rw-r--r--gnu/packages/irc.scm20
-rw-r--r--gnu/packages/linux.scm12
-rw-r--r--gnu/packages/mail.scm73
-rw-r--r--gnu/packages/maths.scm4
-rw-r--r--gnu/packages/messaging.scm15
-rw-r--r--gnu/packages/moreutils.scm12
-rw-r--r--gnu/packages/networking.scm20
-rw-r--r--gnu/packages/openldap.scm37
-rw-r--r--gnu/packages/package-management.scm27
-rw-r--r--gnu/packages/patches/ceph-disable-cpu-optimizations.patch21
-rw-r--r--gnu/packages/patches/fabric-tests.patch15
-rw-r--r--gnu/packages/patches/gcc-libiberty-printf-decl.patch28
-rw-r--r--gnu/packages/patches/graphite2-CVE-2017-5436.patch25
-rw-r--r--gnu/packages/patches/graphite2-check-code-point-limit.patch50
-rw-r--r--gnu/packages/patches/graphite2-fix-32-bit-wrap-arounds.patch93
-rw-r--r--gnu/packages/patches/graphite2-non-linear-classes-even-number.patch26
-rw-r--r--gnu/packages/patches/grub-CVE-2015-8370.patch45
-rw-r--r--gnu/packages/patches/grub-freetype.patch24
-rw-r--r--gnu/packages/patches/grub-gets-undeclared.patch42
-rw-r--r--gnu/packages/patches/guile-arm-fixes.patch203
-rw-r--r--gnu/packages/patches/hurd-fix-eth-multiplexer-dependency.patch26
-rw-r--r--gnu/packages/patches/hypre-doc-tables.patch25
-rw-r--r--gnu/packages/patches/hypre-ldflags.patch9
-rw-r--r--gnu/packages/patches/icecat-avoid-bundled-libraries.patch37
-rw-r--r--gnu/packages/patches/icecat-binutils.patch40
-rw-r--r--gnu/packages/patches/icecat-bug-1299500-pt10.patch1639
-rw-r--r--gnu/packages/patches/icu4c-CVE-2014-6585.patch21
-rw-r--r--gnu/packages/patches/icu4c-CVE-2015-1270.patch15
-rw-r--r--gnu/packages/patches/icu4c-CVE-2015-4760.patch189
-rw-r--r--gnu/packages/patches/icu4c-CVE-2017-7867-CVE-2017-7868.patch164
-rw-r--r--gnu/packages/patches/libbase-fix-includes.patch71
-rw-r--r--gnu/packages/patches/libbase-use-own-logging.patch80
-rw-r--r--gnu/packages/patches/mplayer2-theora-fix.patch286
-rw-r--r--gnu/packages/patches/nss-disable-long-b64-tests.patch34
-rw-r--r--gnu/packages/patches/policycoreutils-make-sepolicy-use-python3.patch335
-rw-r--r--gnu/packages/patches/portaudio-audacity-compat.patch60
-rw-r--r--gnu/packages/patches/python-pyopenssl-skip-network-test.patch25
-rw-r--r--gnu/packages/patches/qemu-CVE-2016-10155.patch49
-rw-r--r--gnu/packages/patches/qemu-CVE-2017-5525.patch55
-rw-r--r--gnu/packages/patches/qemu-CVE-2017-5526.patch58
-rw-r--r--gnu/packages/patches/qemu-CVE-2017-5552.patch44
-rw-r--r--gnu/packages/patches/qemu-CVE-2017-5578.patch39
-rw-r--r--gnu/packages/patches/qemu-CVE-2017-5579.patch44
-rw-r--r--gnu/packages/patches/qemu-CVE-2017-5856.patch68
-rw-r--r--gnu/packages/patches/qemu-CVE-2017-5898.patch44
-rw-r--r--gnu/packages/patches/soprano-find-clucene.patch15
-rw-r--r--gnu/packages/patches/util-linux-CVE-2017-2616.patch65
-rw-r--r--gnu/packages/patches/xf86-video-intel-compat-api.patch13
-rw-r--r--gnu/packages/patches/xf86-video-intel-glibc-2.20.patch15
-rw-r--r--gnu/packages/python.scm40
-rw-r--r--gnu/packages/qemu.scm13
-rw-r--r--gnu/packages/rust.scm56
-rw-r--r--gnu/packages/sdl.scm4
-rw-r--r--gnu/packages/selinux.scm481
-rw-r--r--gnu/packages/serialization.scm25
-rw-r--r--gnu/packages/ssh.scm24
-rw-r--r--gnu/packages/statistics.scm69
-rw-r--r--gnu/packages/suckless.scm46
-rw-r--r--gnu/packages/tls.scm5
-rw-r--r--gnu/packages/tmux.scm5
-rw-r--r--gnu/packages/upnp.scm20
-rw-r--r--gnu/packages/version-control.scm94
-rw-r--r--gnu/packages/video.scm5
-rw-r--r--gnu/packages/web.scm4
-rw-r--r--gnu/packages/xorg.scm23
-rw-r--r--gnu/services/base.scm50
-rw-r--r--gnu/services/mail.scm52
-rw-r--r--gnu/services/web.scm7
-rw-r--r--gnu/system.scm14
-rw-r--r--gnu/system/vm.scm2
-rw-r--r--gnu/tests/mail.scm135
-rw-r--r--guix/build/download.scm7
-rw-r--r--guix/cache.scm113
-rw-r--r--guix/derivations.scm35
-rw-r--r--guix/gexp.scm33
-rw-r--r--guix/scripts/copy.scm41
-rw-r--r--guix/scripts/offload.scm14
-rw-r--r--guix/scripts/publish.scm259
-rwxr-xr-xguix/scripts/substitute.scm97
-rw-r--r--guix/ssh.scm83
-rw-r--r--guix/store.scm122
-rw-r--r--guix/store/ssh.scm39
-rw-r--r--guix/tests.scm6
-rw-r--r--guix/workers.scm123
-rw-r--r--tests/cache.scm88
-rw-r--r--tests/derivations.scm14
-rw-r--r--tests/gexp.scm4
-rw-r--r--tests/guix-build.sh8
-rw-r--r--tests/publish.scm54
-rw-r--r--tests/scripts-build.scm7
-rw-r--r--tests/store.scm8
-rw-r--r--tests/workers.scm45
121 files changed, 5830 insertions, 2192 deletions
diff --git a/.dir-locals.el b/.dir-locals.el
index 917fd3004a..a2d1eb8160 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -68,6 +68,7 @@
 
    (eval . (put 'call-with-container 'scheme-indent-function 1))
    (eval . (put 'container-excursion 'scheme-indent-function 1))
+   (eval . (put 'eventually 'scheme-indent-function 1))
 
    ;; Recognize '~', '+', and '$', as used for gexps, as quotation symbols.
    ;; This notably allows '(' in Paredit to not insert a space when the
diff --git a/.mailmap b/.mailmap
index a3ec47ff44..0d4e752cc8 100644
--- a/.mailmap
+++ b/.mailmap
@@ -40,12 +40,13 @@ Marius Bakke <mbakke@fastmail.com> <m.bakke@warwick.ac.uk>
 Mathieu Lirzin <mthl@gnu.org> <mthl@openmailbox.org>
 Mathieu Lirzin <mthl@gnu.org> <mathieu.lirzin@openmailbox.org>
 Nikita Karetnikov <nikita@karetnikov.org> <nikita.karetnikov@gmail.com>
-ng0 <contact.ng0@cryptolab.net>
-ng0 <contact.ng0@cryptolab.net> <ng0@we.make.ritual.n0.is>
-ng0 <contact.ng0@cryptolab.net> <ngillmann@runbox.com>
-ng0 <contact.ng0@cryptolab.net> <niasterisk@grrlz.net>
-ng0 <contact.ng0@cryptolab.net> <ng@niasterisk.space>
-ng0 <contact.ng0@cryptolab.net> <ng0@libertad.pw>
+ng0 <ng0@no-reply.pragmatique.xyz>
+ng0 <ng0@no-reply.pragmatique.xyz> <contact.ng0@cryptolab.net>
+ng0 <ng0@no-reply.pragmatique.xyz> <ng0@we.make.ritual.n0.is>
+ng0 <ng0@no-reply.pragmatique.xyz> <ngillmann@runbox.com>
+ng0 <ng0@no-reply.pragmatique.xyz> <niasterisk@grrlz.net>
+ng0 <ng0@no-reply.pragmatique.xyz> <ng@niasterisk.space>
+ng0 <ng0@no-reply.pragmatique.xyz> <ng0@libertad.pw>
 Pjotr Prins <pjotr.guix@thebird.nl> <pjotr.public01@thebird.nl>
 Pjotr Prins <pjotr.guix@thebird.nl> <pjotr.public12@thebird.nl>
 Pjotr Prins <pjotr.guix@thebird.nl> <pjotr.public12@email>
diff --git a/Makefile.am b/Makefile.am
index c9671e2d14..db4ebe04dc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -60,7 +60,9 @@ MODULES =					\
   guix/upstream.scm				\
   guix/licenses.scm				\
   guix/graph.scm				\
+  guix/cache.scm				\
   guix/cve.scm					\
+  guix/workers.scm				\
   guix/zlib.scm					\
   guix/build-system.scm				\
   guix/build-system/ant.scm			\
@@ -185,7 +187,8 @@ if HAVE_GUILE_SSH
 
 MODULES +=					\
   guix/ssh.scm					\
-  guix/scripts/copy.scm
+  guix/scripts/copy.scm				\
+  guix/store/ssh.scm
 
 endif HAVE_GUILE_SSH
 
@@ -295,7 +298,9 @@ SCM_TESTS =					\
   tests/size.scm				\
   tests/graph.scm				\
   tests/challenge.scm				\
+  tests/cache.scm				\
   tests/cve.scm					\
+  tests/workers.scm				\
   tests/zlib.scm				\
   tests/file-systems.scm			\
   tests/system.scm				\
diff --git a/doc/guix.texi b/doc/guix.texi
index fd3483ee5d..0d334e302f 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -3666,10 +3666,64 @@ accidental modifications.
 @end quotation
 
 The @code{(guix store)} module provides procedures to connect to the
-daemon, and to perform RPCs.  These are described below.
+daemon, and to perform RPCs.  These are described below.  By default,
+@code{open-connection}, and thus all the @command{guix} commands,
+connect to the local daemon or to the URI specified by the
+@code{GUIX_DAEMON_SOCKET} environment variable.
 
-@deffn {Scheme Procedure} open-connection [@var{file}] [#:reserve-space? #t]
-Connect to the daemon over the Unix-domain socket at @var{file}.  When
+@defvr {Environment Variable} GUIX_DAEMON_SOCKET
+When set, the value of this variable should be a file name or a URI
+designating the daemon endpoint.  When it is a file name, it denotes a
+Unix-domain socket to connect to.  In addition to file names, the
+supported URI schemes are:
+
+@table @code
+@item file
+@itemx unix
+These are for Unix-domain sockets.
+@code{file:///var/guix/daemon-socket/socket} is equivalent to
+@file{/var/guix/daemon-socket/socket}.
+
+@item guix
+These URIs denote connections over TCP/IP, without encryption nor
+authentication of the remote host.  The URI must always specify both the
+host name and port number:
+
+@example
+guix://master.guix.example.org:1234
+@end example
+
+This setup is suitable on local networks, such as clusters, where only
+trusted nodes may connect to the build daemon at
+@code{master.guix.example.org}.
+
+@item ssh
+@cindex SSH access to build daemons
+These URIs allow you to connect to a remote daemon over
+SSH@footnote{This feature requires Guile-SSH (@pxref{Requirements}).}.
+A typical URL might look like this:
+
+@example
+ssh://charlie@@guix.example.org:22
+@end example
+
+As for @command{guix copy}, the usual OpenSSH client configuration files
+are honored (@pxref{Invoking guix copy}).
+@end table
+
+Additional URI schemes may be supported in the future.
+
+@c XXX: Remove this note when the protocol incurs fewer round trips
+@c and when (guix derivations) no longer relies on file system access.
+@quotation Note
+The ability to connect to remote build daemons is considered
+experimental as of @value{VERSION}.  Please get in touch with us to
+share any problems or suggestions you may have (@pxref{Contributing}).
+@end quotation
+@end defvr
+
+@deffn {Scheme Procedure} open-connection [@var{uri}] [#:reserve-space? #t]
+Connect to the daemon over the Unix-domain socket at @var{uri} (a string).  When
 @var{reserve-space?} is true, instruct it to reserve a little bit of
 extra space on the file system so that the garbage collector can still
 operate should the disk become full.  Return a server object.
@@ -6522,6 +6576,13 @@ archive}), the daemon may download substitutes from it:
 guix-daemon --substitute-urls=http://example.org:8080
 @end example
 
+By default, @command{guix publish} compresses archives on the fly as it
+serves them.  This ``on-the-fly'' mode is convenient in that it requires
+no setup and is immediately available.  However, when serving lots of
+clients, we recommend using the @option{--cache} option, which enables
+caching of the archives before they are sent to clients---see below for
+details.
+
 As a bonus, @command{guix publish} also serves as a content-addressed
 mirror for source files referenced in @code{origin} records
 (@pxref{origin Reference}).  For instance, assuming @command{guix
@@ -6559,10 +6620,46 @@ disable compression.  The range 1 to 9 corresponds to different gzip
 compression levels: 1 is the fastest, and 9 is the best (CPU-intensive).
 The default is 3.
 
-Compression occurs on the fly and the compressed streams are not
+Unless @option{--cache} is used, compression occurs on the fly and
+the compressed streams are not
 cached.  Thus, to reduce load on the machine that runs @command{guix
-publish}, it may be a good idea to choose a low compression level, or to
-run @command{guix publish} behind a caching proxy.
+publish}, it may be a good idea to choose a low compression level, to
+run @command{guix publish} behind a caching proxy, or to use
+@option{--cache}.  Using @option{--cache} has the advantage that it
+allows @command{guix publish} to add @code{Content-Length} HTTP header
+to its responses.
+
+@item --cache=@var{directory}
+@itemx -c @var{directory}
+Cache archives and meta-data (@code{.narinfo} URLs) to @var{directory}
+and only serve archives that are in cache.
+
+When this option is omitted, archives and meta-data are created
+on-the-fly.  This can reduce the available bandwidth, especially when
+compression is enabled, since this may become CPU-bound.  Another
+drawback of the default mode is that the length of archives is not known
+in advance, so @command{guix publish} does not add a
+@code{Content-Length} HTTP header to its responses, which in turn
+prevents clients from knowing the amount of data being downloaded.
+
+Conversely, when @option{--cache} is used, the first request for a store
+item (@i{via} a @code{.narinfo} URL) returns 404 and triggers a
+background process to @dfn{bake} the archive---computing its
+@code{.narinfo} and compressing the archive, if needed.  Once the
+archive is cached in @var{directory}, subsequent requests succeed and
+are served directly from the cache, which guarantees that clients get
+the best possible bandwidth.
+
+The ``baking'' process is performed by worker threads.  By default, one
+thread per CPU core is created, but this can be customized.  See
+@option{--workers} below.
+
+When @option{--ttl} is used, cached entries are automatically deleted
+when they have expired.
+
+@item --workers=@var{N}
+When @option{--cache} is used, request the allocation of @var{N} worker
+threads to ``bake'' archives.
 
 @item --ttl=@var{ttl}
 Produce @code{Cache-Control} HTTP headers that advertise a time-to-live
@@ -6574,6 +6671,9 @@ This allows the user's Guix to keep substitute information in cache for
 guarantee that the store items it provides will indeed remain available
 for as long as @var{ttl}.
 
+Additionally, when @option{--cache} is used, cached entries that have
+not been accessed for @var{ttl} may be deleted.
+
 @item --nar-path=@var{path}
 Use @var{path} as the prefix for the URLs of ``nar'' files
 (@pxref{Invoking guix archive, normalized archives}).
@@ -9099,6 +9199,23 @@ compression ratio at the expense of increased CPU usage.
 @item @code{nar-path} (default: @code{"nar"})
 The URL path at which ``nars'' can be fetched.  @xref{Invoking guix
 publish, @code{--nar-path}}, for details.
+
+@item @code{cache} (default: @code{#f})
+When it is @code{#f}, disable caching and instead generate archives on
+demand.  Otherwise, this should be the name of a directory---e.g.,
+@code{"/var/cache/guix/publish"}---where @command{guix publish} caches
+archives and meta-data ready to be sent.  @xref{Invoking guix publish,
+@option{--cache}}, for more information on the tradeoffs involved.
+
+@item @code{workers} (default: @code{#f})
+When it is an integer, this is the number of worker threads used for
+caching; when @code{#f}, the number of processors is used.
+@xref{Invoking guix publish, @option{--workers}}, for more information.
+
+@item @code{ttl} (default: @code{#f})
+When it is an integer, this denotes the @dfn{time-to-live} of the
+published archives.  @xref{Invoking guix publish, @option{--ttl}}, for
+more information.
 @end table
 @end deftp
 
@@ -12591,19 +12708,26 @@ remote servers.  Run @command{man smtpd.conf} for more information.
 
 @subsubheading Exim Service
 
+@cindex mail transfer agent (MTA)
+@cindex MTA (mail transfer agent)
+@cindex SMTP
+
 @deffn {Scheme Variable} exim-service-type
-This is the type of the @uref{https://exim.org, Exim} service, whose value
-should be an @code{exim-configuration} object as in this example:
+This is the type of the @uref{https://exim.org, Exim} mail transfer
+agent (MTA), whose value should be an @code{exim-configuration} object
+as in this example:
 
 @example
 (service exim-service-type
          (exim-configuration
-           (config-file (local-file "./my-exim.conf"))
-           (aliases '(("postmaster" "bob")
-                      ("bob" "bob@@example.com" "bob@@example2.com")))))
+           (config-file (local-file "./my-exim.conf"))))
 @end example
 @end deffn
 
+In order to use an @code{exim-service-type} service you must also have a
+@code{mail-aliases-service-type} service present in your
+@code{operating-system} (even if it has no aliases).
+
 @deftp {Data Type} exim-configuration
 Data type representing the configuration of exim.
 
@@ -12618,16 +12742,37 @@ provided in @code{package}. The resulting configuration file is loaded
 after setting the @code{exim_user} and @code{exim_group} configuration
 variables.
 
-@item @code{aliases} (default: @code{'()})
-List of aliases to use when delivering mail on this system. The
-@code{car} of each list is used to match incoming mail, with the
-@code{cdr} of each list designating how to deliver it. There may be many
-delivery methods provided, in which case the mail is delivered to them
-all.
-
 @end table
 @end deftp
 
+@subsubheading Mail Aliases Service
+
+@cindex email aliases
+@cindex aliases, for email addresses
+
+@deffn {Scheme Variable} mail-aliases-service-type
+This is the type of the service which provides @code{/etc/aliases},
+specifying how to deliver mail to users on this system.
+
+@example
+(service mail-aliases-service-type
+         '(("postmaster" "bob")
+           ("bob" "bob@@example.com" "bob@@example2.com")))
+@end example
+@end deffn
+
+The configuration for a @code{mail-aliases-service-type} service is an
+association list denoting how to deliver mail that comes to this
+system. Each entry is of the form @code{(alias addresses ...)}, with
+@code{alias} specifying the local alias and @code{addresses} specifying
+where to deliver this user's mail.
+
+The aliases aren't required to exist as users on the local system. In
+the above example, there doesn't need to be a @code{postmaster} entry in
+the @code{operating-system}'s @code{user-accounts} in order to deliver
+the @code{postmaster} mail to @code{bob} (which subsequently would
+deliver mail to @code{bob@@example.com} and @code{bob@@example2.com}).
+
 @node Messaging Services
 @subsubsection Messaging Services
 
diff --git a/gnu/local.mk b/gnu/local.mk
index 265157a319..b374a641f0 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -45,6 +45,7 @@ GNU_SYSTEM_MODULES =				\
   %D%/packages/adns.scm				\
   %D%/packages/algebra.scm			\
   %D%/packages/aidc.scm				\
+  %D%/packages/android.scm			\
   %D%/packages/animation.scm			\
   %D%/packages/anthy.scm			\
   %D%/packages/apl.scm				\
@@ -342,6 +343,7 @@ GNU_SYSTEM_MODULES =				\
   %D%/packages/sdl.scm				\
   %D%/packages/search.scm			\
   %D%/packages/security-token.scm		\
+  %D%/packages/selinux.scm			\
   %D%/packages/serialization.scm		\
   %D%/packages/serveez.scm			\
   %D%/packages/shells.scm			\
@@ -552,6 +554,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/eudev-conflicting-declaration.patch	\
   %D%/packages/patches/evilwm-lost-focus-bug.patch		\
   %D%/packages/patches/expat-CVE-2016-0718-fix-regression.patch	\
+  %D%/packages/patches/fabric-tests.patch			\
   %D%/packages/patches/fastcap-mulGlobal.patch			\
   %D%/packages/patches/fastcap-mulSetup.patch			\
   %D%/packages/patches/fasthenry-spAllocate.patch		\
@@ -576,7 +579,6 @@ dist_patch_DATA =						\
   %D%/packages/patches/gcc-arm-bug-71399.patch			\
   %D%/packages/patches/gcc-arm-link-spec-fix.patch		\
   %D%/packages/patches/gcc-cross-environment-variables.patch	\
-  %D%/packages/patches/gcc-libiberty-printf-decl.patch		\
   %D%/packages/patches/gcc-libvtv-runpath.patch			\
   %D%/packages/patches/gcc-strmov-store-file-names.patch	\
   %D%/packages/patches/gcc-4.9.3-mingw-gthr-default.patch	\
@@ -616,14 +618,14 @@ dist_patch_DATA =						\
   %D%/packages/patches/gobject-introspection-absolute-shlib-path.patch \
   %D%/packages/patches/gobject-introspection-cc.patch		\
   %D%/packages/patches/gobject-introspection-girepository.patch	\
+  %D%/packages/patches/graphite2-CVE-2017-5436.patch		\
+  %D%/packages/patches/graphite2-check-code-point-limit.patch	\
   %D%/packages/patches/graphite2-ffloat-store.patch		\
+  %D%/packages/patches/graphite2-fix-32-bit-wrap-arounds.patch	\
+  %D%/packages/patches/graphite2-non-linear-classes-even-number.patch \
   %D%/packages/patches/grep-timing-sensitive-test.patch		\
-  %D%/packages/patches/grub-CVE-2015-8370.patch			\
-  %D%/packages/patches/grub-gets-undeclared.patch		\
-  %D%/packages/patches/grub-freetype.patch			\
   %D%/packages/patches/gsl-test-i686.patch			\
   %D%/packages/patches/guile-1.8-cpp-4.5.patch			\
-  %D%/packages/patches/guile-arm-fixes.patch			\
   %D%/packages/patches/guile-default-utf8.patch			\
   %D%/packages/patches/guile-linux-syscalls.patch		\
   %D%/packages/patches/guile-present-coding.patch		\
@@ -650,14 +652,11 @@ dist_patch_DATA =						\
   %D%/packages/patches/higan-remove-march-native-flag.patch	\
   %D%/packages/patches/hop-linker-flags.patch			\
   %D%/packages/patches/hubbub-sort-entities.patch		\
+  %D%/packages/patches/hurd-fix-eth-multiplexer-dependency.patch        \
   %D%/packages/patches/hydra-disable-darcs-test.patch		\
-  %D%/packages/patches/hypre-doc-tables.patch			\
-  %D%/packages/patches/hypre-ldflags.patch			\
   %D%/packages/patches/icecat-avoid-bundled-libraries.patch	\
-  %D%/packages/patches/icecat-binutils.patch			\
-  %D%/packages/patches/icu4c-CVE-2014-6585.patch		\
-  %D%/packages/patches/icu4c-CVE-2015-1270.patch		\
-  %D%/packages/patches/icu4c-CVE-2015-4760.patch		\
+  %D%/packages/patches/icecat-bug-1299500-pt10.patch		\
+  %D%/packages/patches/icu4c-CVE-2017-7867-CVE-2017-7868.patch	\
   %D%/packages/patches/icu4c-reset-keyword-list-iterator.patch	\
   %D%/packages/patches/id3lib-CVE-2007-4460.patch			\
   %D%/packages/patches/ilmbase-fix-tests.patch			\
@@ -688,6 +687,8 @@ dist_patch_DATA =						\
   %D%/packages/patches/liba52-link-with-libm.patch		\
   %D%/packages/patches/liba52-set-soname.patch			\
   %D%/packages/patches/liba52-use-mtune-not-mcpu.patch		\
+  %D%/packages/patches/libbase-fix-includes.patch		\
+  %D%/packages/patches/libbase-use-own-logging.patch		\
   %D%/packages/patches/libbonobo-activation-test-race.patch	\
   %D%/packages/patches/libcanberra-sound-theme-freedesktop.patch \
   %D%/packages/patches/libdrm-symbol-check.patch		\
@@ -783,7 +784,6 @@ dist_patch_DATA =						\
   %D%/packages/patches/mhash-keygen-test-segfault.patch		\
   %D%/packages/patches/mingw-w64-5.0rc2-gcc-4.9.3.patch		\
   %D%/packages/patches/mpc123-initialize-ao.patch		\
-  %D%/packages/patches/mplayer2-theora-fix.patch		\
   %D%/packages/patches/module-init-tools-moduledir.patch	\
   %D%/packages/patches/mozjs17-aarch64-support.patch		\
   %D%/packages/patches/mozjs24-aarch64-support.patch		\
@@ -804,6 +804,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/ngircd-handle-zombies.patch		\
   %D%/packages/patches/ninja-zero-mtime.patch			\
   %D%/packages/patches/node-9077.patch				\
+  %D%/packages/patches/nss-disable-long-b64-tests.patch		\
   %D%/packages/patches/nss-increase-test-timeout.patch		\
   %D%/packages/patches/nss-pkgconfig.patch			\
   %D%/packages/patches/ntfs-3g-CVE-2017-0358.patch		\
@@ -858,6 +859,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/plink-endian-detection.patch		\
   %D%/packages/patches/plotutils-libpng-jmpbuf.patch		\
   %D%/packages/patches/polkit-drop-test.patch			\
+  %D%/packages/patches/policycoreutils-make-sepolicy-use-python3.patch	\
   %D%/packages/patches/portaudio-audacity-compat.patch		\
   %D%/packages/patches/portmidi-modular-build.patch		\
   %D%/packages/patches/procmail-ambiguous-getline-debian.patch  \
@@ -899,14 +901,6 @@ dist_patch_DATA =						\
   %D%/packages/patches/python2-pygobject-2-gi-info-type-error-domain.patch \
   %D%/packages/patches/python-pygpgme-fix-pinentry-tests.patch	\
   %D%/packages/patches/python2-subprocess32-disable-input-test.patch	\
-  %D%/packages/patches/qemu-CVE-2016-10155.patch			\
-  %D%/packages/patches/qemu-CVE-2017-5525.patch			\
-  %D%/packages/patches/qemu-CVE-2017-5526.patch			\
-  %D%/packages/patches/qemu-CVE-2017-5552.patch			\
-  %D%/packages/patches/qemu-CVE-2017-5578.patch			\
-  %D%/packages/patches/qemu-CVE-2017-5579.patch			\
-  %D%/packages/patches/qemu-CVE-2017-5856.patch			\
-  %D%/packages/patches/qemu-CVE-2017-5898.patch			\
   %D%/packages/patches/qt4-ldflags.patch			\
   %D%/packages/patches/quickswitch-fix-dmenu-check.patch	\
   %D%/packages/patches/rapicorn-isnan.patch			\
@@ -938,7 +932,6 @@ dist_patch_DATA =						\
   %D%/packages/patches/slim-reset.patch				\
   %D%/packages/patches/slim-login.patch				\
   %D%/packages/patches/slurm-configure-remove-nonfree-contribs.patch \
-  %D%/packages/patches/soprano-find-clucene.patch		\
   %D%/packages/patches/spice-CVE-2016-9577.patch		\
   %D%/packages/patches/spice-CVE-2016-9578-1.patch		\
   %D%/packages/patches/spice-CVE-2016-9578-2.patch		\
@@ -987,7 +980,6 @@ dist_patch_DATA =						\
   %D%/packages/patches/unzip-remove-build-date.patch		\
   %D%/packages/patches/ustr-fix-build-with-gcc-5.patch		\
   %D%/packages/patches/util-linux-tests.patch			\
-  %D%/packages/patches/util-linux-CVE-2017-2616.patch		\
   %D%/packages/patches/upower-builddir.patch			\
   %D%/packages/patches/valgrind-enable-arm.patch		\
   %D%/packages/patches/virglrenderer-CVE-2017-6386.patch 	\
@@ -1018,8 +1010,6 @@ dist_patch_DATA =						\
   %D%/packages/patches/xf86-video-ast-remove-mibstore.patch	\
   %D%/packages/patches/xf86-video-geode-glibc-2.20.patch	\
   %D%/packages/patches/xf86-video-i128-remove-mibstore.patch	\
-  %D%/packages/patches/xf86-video-intel-compat-api.patch	\
-  %D%/packages/patches/xf86-video-intel-glibc-2.20.patch	\
   %D%/packages/patches/xf86-video-mach64-glibc-2.20.patch	\
   %D%/packages/patches/xf86-video-tga-remove-mibstore.patch	\
   %D%/packages/patches/xfce4-panel-plugins.patch		\
diff --git a/gnu/packages/admin.scm b/gnu/packages/admin.scm
index 4daaddcfec..8f4a4cd41e 100644
--- a/gnu/packages/admin.scm
+++ b/gnu/packages/admin.scm
@@ -12,10 +12,10 @@
 ;;; Copyright © 2016, 2017 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2016 Peter Feigl <peter.feigl@nexoid.at>
 ;;; Copyright © 2016 John J. Foerch <jjfoerch@earthlink.net>
-;;; Coypright © 2016, 2017 ng0 <contact.ng0@cryptolab.net>
-;;; Coypright © 2016 Tobias Geerinckx-Rice <me@tobias.gr>
-;;; Coypright © 2016 John Darrington <jmd@gnu.org>
-;;; Coypright © 2017 Ben Sturmfels <ben@sturm.com.au>
+;;; Copyright © 2016, 2017 ng0 <contact.ng0@cryptolab.net>
+;;; Copyright © 2016 Tobias Geerinckx-Rice <me@tobias.gr>
+;;; Copyright © 2016 John Darrington <jmd@gnu.org>
+;;; Copyright © 2017 Ben Sturmfels <ben@sturm.com.au>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -2060,11 +2060,15 @@ Intel DRM Driver.")
        (uri (pypi-uri "Fabric" version))
        (sha256
         (base32
-         "1z17hw0yiqp1blq217zxkg2jzkv8qd79saqhscgsw14mwlcqpwd0"))))
+         "1z17hw0yiqp1blq217zxkg2jzkv8qd79saqhscgsw14mwlcqpwd0"))
+       (patches (search-patches "fabric-tests.patch"))))
     (build-system python-build-system)
     (arguments
-     `(#:tests? #f     ;XXX: Tests attempt to download Python "fudge" package.
-       #:python ,python-2))                       ;Python 2 only
+     `(#:python ,python-2))                       ;Python 2 only
+    (native-inputs
+     `(("python2-fudge" ,python2-fudge) ; Requires < 1.0
+       ("python2-jinja2" ,python2-jinja2) ; Requires < 3.0
+       ("python2-nose" ,python2-nose))) ; Requires < 2.0
     (propagated-inputs
      ;; Required upgrading python-paramiko 1.17.4 to fix an incompatibility
      ;; between python-paramiko and newer python-pycrypto. Without this, the
diff --git a/gnu/packages/android.scm b/gnu/packages/android.scm
new file mode 100644
index 0000000000..e23d0fd910
--- /dev/null
+++ b/gnu/packages/android.scm
@@ -0,0 +1,300 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2012 Stefan Handschuh <handschuh.stefan@googlemail.com>
+;;; Copyright © 2015 Kai-Chung Yan <seamlikok@gmail.com>
+;;; Copyright © 2016 Marius Bakke <mbakke@fastmail.com>
+;;; Copyright © 2017 Julien Lepiller <julien@lepiller.eu>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu packages android)
+  #:use-module (guix packages)
+  #:use-module (guix git-download)
+  #:use-module (guix build-system gnu)
+  #:use-module ((guix licenses) #:prefix license:)
+  #:use-module (gnu packages)
+  #:use-module (gnu packages tls))
+
+;; The Makefiles that we add are largely based on the Debian
+;; packages.  They are licensed under GPL-2 and have copyright:
+;; 2012, Stefan Handschuh <handschuh.stefan@googlemail.com>
+;; 2015, Kai-Chung Yan <seamlikok@gmail.com>
+;; Big thanks to them for laying the groundwork.
+
+;; The version tag is consistent between all repositories.
+(define (android-platform-version) "7.1.2_r6")
+
+(define (android-platform-system-core version)
+  (origin
+    (method git-fetch)
+    (uri (git-reference
+          (url "https://android.googlesource.com/platform/system/core")
+          (commit (string-append "android-" version))))
+    (file-name (string-append "android-platform-system-core-"
+                              version "-checkout"))
+    (sha256
+     (base32
+      "0xc2n7jxrf1iw9cc278pijdfjix2fkiig5ws27f6rwp40zg5mrgg"))))
+
+(define liblog
+  (package
+    (name "liblog")
+    (version (android-platform-version))
+    (source (android-platform-system-core version))
+    (build-system gnu-build-system)
+    (arguments
+     `(#:tests? #f ; TODO.
+       #:make-flags '("CC=gcc")
+       #:phases
+       (modify-phases %standard-phases
+         (add-after 'unpack 'enter-source
+           (lambda _ (chdir "liblog") #t))
+         (add-after 'enter-source 'create-Makefile
+           (lambda _
+             ;; No useful makefile is shipped, so we create one.
+             (with-output-to-file "Makefile"
+               (lambda _
+                 (display
+                  (string-append
+                   "NAME = liblog\n"
+                   "SOURCES = log_event_list.c log_event_write.c"
+                   " logger_write.c config_write.c logger_name.c"
+                   " logger_lock.c fake_log_device.c fake_writer.c"
+                   " event_tag_map.c\n"
+
+                   "CFLAGS += -fvisibility=hidden -fPIC\n"
+                   "CPPFLAGS += -I../include -DFAKE_LOG_DEVICE=1"
+                   ;; Keep these two in sync with "liblog/Android.bp".
+                   " -DLIBLOG_LOG_TAG=1005"
+                   " -DSNET_EVENT_LOG_TAG=1397638484\n"
+                   "LDFLAGS += -shared -Wl,-soname,$(NAME).so.0 -lpthread\n"
+
+                   "build: $(SOURCES)\n"
+                   "	$(CC) $^ -o $(NAME).so.0 $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)\n"))
+                 #t))))
+         (delete 'configure)
+         (replace 'install
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let* ((out (assoc-ref outputs "out"))
+                    (lib (string-append out "/lib")))
+               (install-file "liblog.so.0" lib)
+               (with-directory-excursion lib
+                 (symlink "liblog.so.0" "liblog.so"))
+               #t))))))
+    (home-page "https://developer.android.com/")
+    (synopsis "Logging library from the Android platform.")
+    (description "@code{liblog} represents an interface to the volatile Android
+Logging system for NDK (Native) applications and libraries and contain
+interfaces for either writing or reading logs.  The log buffers are divided up
+in Main, System, Radio and Events sub-logs.")
+    (license license:asl2.0)))
+
+(define libbase
+  (package
+    (name "libbase")
+    (version (android-platform-version))
+    (source (origin
+              (inherit (android-platform-system-core version))
+              (patches
+               (search-patches "libbase-use-own-logging.patch"
+                               "libbase-fix-includes.patch"))))
+    (build-system gnu-build-system)
+    (arguments
+     `(#:tests? #f ; TODO.
+       #:phases
+       (modify-phases %standard-phases
+         (add-after 'unpack 'enter-source
+           (lambda _ (chdir "base") #t))
+         (add-after 'enter-source 'create-Makefile
+           (lambda _
+             ;; No useful makefile is shipped, so we create one.
+             (with-output-to-file "Makefile"
+               (lambda _
+                 (display
+                  (string-append
+                   "NAME = libbase\n"
+                   "SOURCES = file.cpp logging.cpp parsenetaddress.cpp"
+                   " stringprintf.cpp strings.cpp errors_unix.cpp\n"
+
+                   "CXXFLAGS += -std=gnu++11 -fPIC\n"
+                   "CPPFLAGS += -Iinclude -I../include\n"
+                   "LDFLAGS += -shared -Wl,-soname,$(NAME).so.0"
+                   " -L.. -llog\n"
+
+                   "build: $(SOURCES)\n"
+                   "	$(CXX) $^ -o $(NAME).so.0 $(CXXFLAGS) $(CPPFLAGS)"
+                   " $(LDFLAGS)\n"))
+                 #t))))
+         (delete 'configure)
+         (replace 'install
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let* ((out (assoc-ref outputs "out"))
+                    (lib (string-append out "/lib")))
+               (install-file "libbase.so.0" lib)
+               (with-directory-excursion lib
+                 (symlink "libbase.so.0" "libbase.so"))
+               (copy-recursively "include" out)
+               #t))))))
+    (inputs `(("liblog" ,liblog)))
+    (home-page "https://developer.android.com/")
+    (synopsis "Android platform base library")
+    (description "@code{libbase} is a library in common use by the
+various Android core host applications.")
+    (license license:asl2.0)))
+
+(define libcutils
+  (package
+    (name "libcutils")
+    (version (android-platform-version))
+    (source (android-platform-system-core version))
+    (build-system gnu-build-system)
+    (arguments
+     `(#:tests? #f ; TODO.
+       #:phases
+       (modify-phases %standard-phases
+         (add-after 'unpack 'enter-source
+           (lambda _ (chdir "libcutils") #t))
+         (add-after 'enter-source 'create-Makefile
+           (lambda _
+             ;; No useful makefile is shipped, so we create one.
+             (with-output-to-file "Makefile"
+               (lambda _
+                 (display
+                  (string-append
+                   "NAME = libcutils\n"
+                   "SOURCES = load_file.o socket_local_client_unix.o"
+                   " socket_loopback_client_unix.o socket_network_client_unix.o"
+                   " socket_loopback_server_unix.o socket_local_server_unix.o"
+                   " sockets_unix.o socket_inaddr_any_server_unix.o"
+                   " sockets.o\n"
+                   "CC = gcc\n"
+
+                   "CFLAGS += -fPIC\n"
+                   "CXXFLAGS += -std=gnu++11 -fPIC\n"
+                   "CPPFLAGS += -Iinclude -I../include\n"
+                   "LDFLAGS += -shared -Wl,-soname,$(NAME).so.0\n"
+
+                   "build: $(SOURCES)\n"
+                   "	$(CXX) $^ -o $(NAME).so.0 $(CXXFLAGS) $(CPPFLAGS)"
+                   " $(LDFLAGS)\n"))
+                 #t))))
+         (delete 'configure)
+         (replace 'install
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let* ((out (assoc-ref outputs "out"))
+                    (lib (string-append out "/lib")))
+               (install-file "libcutils.so.0" lib)
+               (with-directory-excursion lib
+                 (symlink "libcutils.so.0" "libcutils.so"))
+               #t))))))
+    (home-page "https://developer.android.com/")
+    (synopsis "Android platform c utils library")
+    (description "@code{libcutils} is a library in common use by the
+various Android core host applications.")
+    (license license:asl2.0)))
+
+(define-public adb
+  (package
+    (name "adb")
+    (version (android-platform-version))
+    (source (origin
+              (inherit (android-platform-system-core version))
+              (patches
+               (search-patches "libbase-use-own-logging.patch"
+                               "libbase-fix-includes.patch"))))
+    (build-system gnu-build-system)
+    (arguments
+     `(#:phases
+       (modify-phases %standard-phases
+         (add-after 'unpack 'enter-source
+           (lambda _ (chdir "adb") #t))
+         (add-before 'build 'fix-clang
+           (lambda _
+             ;; adb_client.h contains _Nonnull and _Nullable attributes, that
+             ;; are not understood by gcc.
+             (substitute* "adb_client.h"
+                   (("_Nonnull") "")
+                   (("_Nullable") ""))
+             #t))
+         (add-before 'build 'fix-main
+           (lambda _
+             ;; main.cpp used to be adb_main.cpp in the current directory
+             ;; rather than in its own subdirectory, but it was not fixed.
+             ;; This leads to some header files not being found anymore.
+             (copy-file "client/main.cpp" "adb_main.cpp")
+             #t))
+         (add-after 'enter-source 'create-Makefile
+           (lambda* (#:key outputs #:allow-other-keys)
+             ;; No useful makefile is shipped, so we create one.
+             (with-output-to-file "Makefile"
+               (lambda _
+                 (display
+                  (string-append
+                   ;; Common for all components.
+                   "CXXFLAGS += -std=gnu++14 -fpermissive\n"
+                   "CPPFLAGS += -I../include -I../base/include -I. -DADB_HOST=1 "
+                   "-DADB_REVISION='\"" ,version "\"' -fPIC\n"
+                   "LDFLAGS += -lcrypto -lpthread -lbase -lcutils -L. -ladb\n"
+
+                   ;; Libadb specifics.
+                   "LIBADB_SOURCES = adb.cpp adb_auth.cpp adb_io.cpp "
+                   "adb_listeners.cpp adb_trace.cpp adb_utils.cpp fdevent.cpp "
+                   "sockets.cpp transport.cpp transport_local.cpp transport_usb.cpp "
+                   "get_my_path_linux.cpp sysdeps_unix.cpp usb_linux.cpp "
+                   "adb_auth_host.cpp diagnose_usb.cpp services.cpp "
+                   "shell_service_protocol.cpp bugreport.cpp line_printer.cpp\n"
+
+                   "LIBADB_LDFLAGS += -shared -Wl,-soname,libadb.so.0 "
+                   "-lcrypto -lpthread -lbase\n"
+
+                   ;; Adb specifics.
+                   "ADB_SOURCES = adb_main.cpp console.cpp commandline.cpp "
+                   "adb_client.cpp file_sync_client.cpp\n"
+                   "ADB_LDFLAGS += -Wl,-rpath=" (assoc-ref outputs "out") "/lib\n"
+
+                   "build: libadb $(ADB_SOURCES)\n"
+                   "	$(CXX) $(ADB_SOURCES) -o adb $(CXXFLAGS) $(CPPFLAGS) "
+                   "$(ADB_LDFLAGS) $(LDFLAGS)\n"
+
+                   "libadb: $(LIBADB_SOURCES)\n"
+                   "	$(CXX) $^ -o libadb.so.0 $(CXXFLAGS) $(CPPFLAGS) "
+                   "$(LIBADB_LDFLAGS)\n"
+                   "	ln -sv libadb.so.0 libadb.so\n"))
+                 #t))))
+         (delete 'configure)
+         (replace 'install
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let* ((out (assoc-ref outputs "out"))
+                    (lib (string-append out "/lib"))
+                    (bin (string-append out "/bin")))
+               (install-file "libadb.so.0" lib)
+               (install-file "adb" bin)
+               (with-directory-excursion lib
+                 (symlink "libadb.so.0" "libadb.so"))
+               #t))))
+       ;; Test suite must be run with attached devices
+       #:tests? #f))
+    (inputs
+     `(("libbase" ,libbase)
+       ("libcutils" ,libcutils)
+       ("openssl" ,openssl)))
+    (home-page "https://developer.android.com/studio/command-line/adb.html")
+    (synopsis "Android Debug Bridge")
+    (description
+     "@command{adb} is a versatile command line tool that lets you communicate
+with an emulator instance or connected Android device.  It facilitates a variety
+of device actions, such as installing and debugging apps, and it provides access
+to a Unix shell that can run commands on the connected device or emulator.")
+    (license license:asl2.0)))
diff --git a/gnu/packages/audio.scm b/gnu/packages/audio.scm
index f4421df18a..5b2d971953 100644
--- a/gnu/packages/audio.scm
+++ b/gnu/packages/audio.scm
@@ -2379,7 +2379,7 @@ can play and record audio files.")
 (define-public soxr
   (package
     (name "soxr")
-    (version "0.1.1")
+    (version "0.1.2")
     (source
      (origin
        (method url-fetch)
@@ -2387,7 +2387,7 @@ can play and record audio files.")
         (string-append "mirror://sourceforge/soxr/soxr-" version
                        "-Source.tar.xz"))
        (sha256
-        (base32 "1hmadwqfpg15vhwq9pa1sl5xslibrjpk6hpq2s9hfmx1s5l6ihfw"))))
+        (base32 "0xf2w3piwz9gfr1xqyrj4k685q5dy53kq3igv663i4f4y4sg9rjl"))))
     (build-system cmake-build-system)
     (arguments '(#:tests? #f))          ;no 'check' target
     (home-page "https://sourceforge.net/p/soxr/wiki/Home/")
@@ -2433,7 +2433,7 @@ portions of LAME.")
 (define-public portaudio
   (package
     (name "portaudio")
-    (version "19.20140130")
+    (version "190600.20161030")
     (source
      (origin
        (method url-fetch)
@@ -2442,7 +2442,7 @@ portions of LAME.")
              (string-map (lambda (c) (if (char=? c #\.) #\_ c)) version)
              ".tgz"))
        (sha256
-        (base32 "0mwddk4qzybaf85wqfhxqlf0c5im9il8z03rd4n127k8y2jj9q4g"))
+        (base32 "04qmin6nj144b8qb9kkd9a52xfvm0qdgm8bg8jbl7s3frmyiv8pm"))
        (patches (search-patches "portaudio-audacity-compat.patch"))))
     (build-system gnu-build-system)
     (inputs
diff --git a/gnu/packages/autotools.scm b/gnu/packages/autotools.scm
index e8b087000f..4dbe7b2a21 100644
--- a/gnu/packages/autotools.scm
+++ b/gnu/packages/autotools.scm
@@ -3,7 +3,7 @@
 ;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2015 Mathieu Lirzin <mthl@openmailbox.org>
 ;;; Copyright © 2014 Manolis Fragkiskos Ragkousis <manolis837@gmail.com>
-;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
+;;; Copyright © 2015, 2017 Mark H Weaver <mhw@netris.org>
 ;;; Copyright © 2016 David Thompson <davet@gnu.org>
 ;;; Copyright © 2017 ng0 <ng0@libertad.pw>
 ;;;
@@ -92,6 +92,35 @@ know anything about Autoconf or M4.")
        (base32
         "0j3jdjpf5ly39dlp0bg70h72nzqr059k0x8iqxvaxf106chpgn9j"))))))
 
+(define-public autoconf-2.13
+  ;; GNU IceCat 52.x requires autoconf-2.13 to build!
+  (package (inherit autoconf)
+    (version "2.13")
+    (source
+     (origin
+      (method url-fetch)
+      (uri (string-append "mirror://gnu/autoconf/autoconf-"
+                          version ".tar.gz"))
+      (sha256
+       (base32
+        "07krzl4czczdsgzrrw9fiqx35xcf32naf751khg821g5pqv12qgh"))))
+    (arguments
+     `(#:tests? #f
+       #:phases
+       ;; The 'configure' script in autoconf-2.13 can't cope with "SHELL=" and
+       ;; "CONFIG_SHELL=" arguments, so we set them as environment variables
+       ;; and pass a simplified set of arguments.
+       (modify-phases %standard-phases
+         (replace 'configure
+           (lambda* (#:key build inputs outputs #:allow-other-keys)
+             (let ((bash (which "bash"))
+                   (out  (assoc-ref outputs "out")))
+               (setenv "CONFIG_SHELL" bash)
+               (setenv "SHELL" bash)
+               (zero? (system* bash "./configure"
+                               (string-append "--prefix=" out)
+                               (string-append "--build=" build)))))))))))
+
 
 (define* (autoconf-wrapper #:optional (autoconf autoconf))
   "Return an wrapper around AUTOCONF that generates `configure' scripts that
diff --git a/gnu/packages/base.scm b/gnu/packages/base.scm
index 072f401fc3..9591d9de54 100644
--- a/gnu/packages/base.scm
+++ b/gnu/packages/base.scm
@@ -7,6 +7,7 @@
 ;;; Copyright © 2014, 2015 Manolis Fragkiskos Ragkousis <manolis837@gmail.com>
 ;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
+;;; Copyright © 2017 Marius Bakke <mbakke@fastmail.com>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -361,6 +362,22 @@ functionality beyond that which is outlined in the POSIX standard.")
    (license gpl3+)
    (home-page "https://www.gnu.org/software/coreutils/")))
 
+;; We add version 8.27 here for use in (gnu system) due to a time
+;; zone bug in `date' versions 8.25 - 8.26.
+;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=23035
+;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=26238
+(define-public coreutils-8.27
+  (package
+    (inherit coreutils)
+    (version "8.27")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "mirror://gnu/coreutils/coreutils-"
+                                  version ".tar.xz"))
+              (sha256
+               (base32
+                "0sv547572iq8ayy8klir4hnngnx92a9nsazmf1wgzfc7xr4x74c8"))))))
+
 (define-public coreutils-minimal
   ;; Coreutils without its optional dependencies.
   (package
diff --git a/gnu/packages/bioinformatics.scm b/gnu/packages/bioinformatics.scm
index 2b0303b06d..d270db9b53 100644
--- a/gnu/packages/bioinformatics.scm
+++ b/gnu/packages/bioinformatics.scm
@@ -2084,7 +2084,7 @@ identify enrichments with functional annotations of the genome.")
 (define-public diamond
   (package
     (name "diamond")
-    (version "0.8.37")
+    (version "0.8.38")
     (source (origin
               (method url-fetch)
               (uri (string-append
@@ -2093,7 +2093,7 @@ identify enrichments with functional annotations of the genome.")
               (file-name (string-append name "-" version ".tar.gz"))
               (sha256
                (base32
-                "1zn7q8m41ayfnjvf9snrsnq00mm68alf9rhdadx5q1sk23lyvp2l"))))
+                "0q2z6z5f7c0kbbzpjamkcyqg0rc6h5rxfp97qbmb0wxaycr7jajq"))))
     (build-system cmake-build-system)
     (arguments
      '(#:tests? #f ; no "check" target
@@ -3805,7 +3805,7 @@ predicts the locations of structural units in the sequences.")
 (define-public proteinortho
   (package
     (name "proteinortho")
-    (version "5.15")
+    (version "5.16")
     (source
      (origin
       (method url-fetch)
@@ -3815,7 +3815,7 @@ predicts the locations of structural units in the sequences.")
         version "_src.tar.gz"))
       (sha256
        (base32
-        "05wacnnbx56avpcwhzlcf6b7s77swcpv3qnwz5sh1z54i51gg2ki"))))
+        "0z4f5cg0cs8ai62hfvp4q6w66q2phcc55nhs4xj5cyhxxivjv2ai"))))
     (build-system gnu-build-system)
     (arguments
      `(#:test-target "test"
@@ -8275,14 +8275,14 @@ unmodeled, or latent sources of noise.")
 (define-public r-seqminer
   (package
     (name "r-seqminer")
-    (version "5.7")
+    (version "5.9")
     (source
      (origin
        (method url-fetch)
        (uri (cran-uri "seqminer" version))
        (sha256
         (base32
-         "0p75wyl70cvp36mwg5y74nv573j1gdqi15ac2a7xf61jmsq7ycpy"))))
+         "0sfkxrc9gy5a8fadzyzfzh7l5grasm8cj6cd2nnpv85ws6mqr6qd"))))
     (build-system r-build-system)
     (inputs
      `(("zlib" ,zlib)))
diff --git a/gnu/packages/build-tools.scm b/gnu/packages/build-tools.scm
index 8901a46576..0f6a10bbc7 100644
--- a/gnu/packages/build-tools.scm
+++ b/gnu/packages/build-tools.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2017 Ricardo Wurmus <rekado@elephly.net>
+;;; Copyright © 2017 Corentin Bocquillon <corentin@nybble.fr>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -23,7 +24,9 @@
   #:use-module (guix download)
   #:use-module (gnu packages)
   #:use-module (gnu packages python)
-  #:use-module (guix build-system gnu))
+  #:use-module (gnu packages ninja)
+  #:use-module (guix build-system gnu)
+  #:use-module (guix build-system python))
 
 (define-public bam
   (package
@@ -62,3 +65,28 @@ describe the build process.  It takes its inspiration for the script files
 from scons.  While scons focuses on being 100% correct when building, bam
 makes a few sacrifices to acquire fast full and incremental build times.")
     (license license:bsd-3)))
+
+(define-public meson
+  (package
+    (name "meson")
+    (version "0.39.1")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "https://github.com/mesonbuild/meson/"
+                                  "archive/" version ".tar.gz"))
+              (file-name (string-append name "-" version ".tar.gz"))
+              (sha256
+               (base32
+                "1jwgd6sl7zl7h16id3405gwk6vlkk86ggwrp0k47njwkxmryq8d4"))))
+    (build-system python-build-system)
+    (inputs `(("ninja", ninja)))
+    (home-page "https://mesonbuild.com/")
+    (synopsis "Build system designed to be fast and user-friendly")
+    (description
+     "The Meson build system is focused on user-friendliness and speed.
+It can compile code written in C, C++, Fortran, Java, Rust, and other
+languages.  Meson provides features comparable to those of the
+Autoconf/Automake/make combo.  Build specifications, also known as @dfn{Meson
+files}, are written in a custom domain-specific language (DSL) that resembles
+Python.")
+    (license license:asl2.0)))
diff --git a/gnu/packages/certs.scm b/gnu/packages/certs.scm
index 4b43348a50..85a8badc55 100644
--- a/gnu/packages/certs.scm
+++ b/gnu/packages/certs.scm
@@ -74,7 +74,7 @@
 (define-public nss-certs
   (package
     (name "nss-certs")
-    (version "3.30")
+    (version "3.30.2")
     (source (origin
               (method url-fetch)
               (uri (let ((version-with-underscores
@@ -85,7 +85,7 @@
                       "nss-" version ".tar.gz")))
               (sha256
                (base32
-                "1agkkwb51si4raw46p44vl3d0l7wzvdjcblpcdjjz6aymq6h1h58"))))
+                "096frzvyp3z257x84rxknscfgsbavzh2a0gyibx7kvmw4vzpfjhd"))))
     (build-system gnu-build-system)
     (outputs '("out"))
     (native-inputs
diff --git a/gnu/packages/crypto.scm b/gnu/packages/crypto.scm
index fd2b5a36b7..856308afe8 100644
--- a/gnu/packages/crypto.scm
+++ b/gnu/packages/crypto.scm
@@ -56,7 +56,7 @@
 (define-public libsodium
   (package
     (name "libsodium")
-    (version "1.0.11")
+    (version "1.0.12")
     (source (origin
             (method url-fetch)
             (uri (list (string-append
@@ -67,7 +67,7 @@
                         "releases/old/libsodium-" version ".tar.gz")))
             (sha256
              (base32
-              "0rf7z6bgpnf8lyz8sph4h43fbb28pmj4dgybf0hsxxj97kdljid1"))))
+              "159givfh5jgli3cifxgssivkklfyfq6lzyjgrx8h4jx5ncdqyr5q"))))
     (build-system gnu-build-system)
     (synopsis "Portable NaCl-based crypto library")
     (description
diff --git a/gnu/packages/curl.scm b/gnu/packages/curl.scm
index 22e18389e7..73d402ce18 100644
--- a/gnu/packages/curl.scm
+++ b/gnu/packages/curl.scm
@@ -40,6 +40,7 @@
 (define-public curl
   (package
    (name "curl")
+   (replacement curl-7.54.0)
    (version "7.53.0")
    (source (origin
             (method url-fetch)
@@ -119,3 +120,16 @@ tunneling, and so on.")
    (license (license:non-copyleft "file://COPYING"
                                   "See COPYING in the distribution."))
    (home-page "https://curl.haxx.se/")))
+
+(define curl-7.54.0
+  (package
+    (inherit curl)
+    (version "7.54.0")
+    (source
+      (origin
+        (method url-fetch)
+        (uri (string-append "https://curl.haxx.se/download/curl-"
+                            version ".tar.lzma"))
+        (sha256
+         (base32
+          "02h7qhl8ynp75g1vcaw18ks0gp7nahvvkqck19pb1q0kkw1scsnd"))))))
diff --git a/gnu/packages/emacs.scm b/gnu/packages/emacs.scm
index 6eb8751ad9..47ea8d43a1 100644
--- a/gnu/packages/emacs.scm
+++ b/gnu/packages/emacs.scm
@@ -97,14 +97,14 @@
 (define-public emacs
   (package
     (name "emacs")
-    (version "25.1")
+    (version "25.2")
     (source (origin
              (method url-fetch)
              (uri (string-append "mirror://gnu/emacs/emacs-"
                                  version ".tar.xz"))
              (sha256
               (base32
-               "0cwgyiyymnx4xdg99dm2drfxcyhy2jmyf0rkr9fwj9mwwf77kwhr"))
+               "1ykkq0xl28ljdg61bm6gzy04ww86ajms98gix72qg6cpr6a53dar"))
              (patches (search-patches "emacs-exec-path.patch"
                                       "emacs-fix-scheme-indent-function.patch"
                                       "emacs-source-date-epoch.patch"))
@@ -1406,7 +1406,13 @@ type, for example: packages, buffers, files, etc.")
              (magit-popup (assoc-ref %build-inputs "magit-popup"))
              (site-lisp   "/share/emacs/site-lisp"))
          (list (string-append "--with-guix-site-dir="
-                              guix "/share/guile/site/2.0")
+                              (car (find-files (string-append guix
+                                                           "/share/guile/site")
+                                               (lambda (file stat)
+                                                 (string-prefix?
+                                                  "2."
+                                                  (basename file)))
+                                               #:directories? #t)))
                (string-append "--with-geiser-lispdir=" geiser site-lisp)
                (string-append "--with-dash-lispdir="
                               dash site-lisp "/guix.d/dash-"
@@ -4475,7 +4481,7 @@ It should enable you to implement low-level X11 applications.")
                    (format #t "#!~a ~@
                      export DISPLAY=:0 ~@
                      ~a +SI:localuser:$USER ~@
-                     exec ~a --exit-with-session ~a --eval '~s' ~%"
+                     exec ~a --exit-with-session ~a \"$@\" --eval '~s' ~%"
                            (string-append (assoc-ref inputs "bash") "/bin/sh")
                            (string-append (assoc-ref inputs "xhost") "/bin/xhost")
                            (string-append (assoc-ref inputs "dbus") "/bin/dbus-launch")
diff --git a/gnu/packages/fontutils.scm b/gnu/packages/fontutils.scm
index 7e7234960d..cc6d1df597 100644
--- a/gnu/packages/fontutils.scm
+++ b/gnu/packages/fontutils.scm
@@ -376,6 +376,7 @@ applications should be.")
   (package
    (name "graphite2")
    (version "1.3.9")
+   (replacement graphite2/fixed)
    (source
      (origin
        (method url-fetch)
@@ -400,6 +401,27 @@ and returns a sequence of positioned glyphids from the font.")
    (license license:lgpl2.1+)
    (home-page "https://github.com/silnrsi/graphite")))
 
+(define graphite2/fixed
+  (package
+    (inherit graphite2)
+    (name "graphite2")
+    (version "1.3.9")
+    (replacement #f)
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "https://github.com/silnrsi/graphite/releases/"
+                           "download/" version "/" name "-" version ".tgz"))
+       (patches (search-patches
+                 "graphite2-ffloat-store.patch"
+                 "graphite2-check-code-point-limit.patch"
+                 "graphite2-CVE-2017-5436.patch"
+                 "graphite2-fix-32-bit-wrap-arounds.patch"
+                 "graphite2-non-linear-classes-even-number.patch"))
+       (sha256
+        (base32
+         "0rs5h7m340z75kygx8d72cps0q6yvvqa9i788vym7585cfv8a0gc"))))))
+
 (define-public potrace
   (package
     (name "potrace")
diff --git a/gnu/packages/freedesktop.scm b/gnu/packages/freedesktop.scm
index b912ce0260..85a6c8b26d 100644
--- a/gnu/packages/freedesktop.scm
+++ b/gnu/packages/freedesktop.scm
@@ -8,6 +8,7 @@
 ;;; Copyright © 2016, 2017 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2016 Kei Kebreau <kei@openmailbox.org>
 ;;; Copyright © 2017 Mark H Weaver <mhw@netris.org>
+;;; Copyright © 2017 Marius Bakke <mbakke@fastmail.com>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -55,6 +56,7 @@
   #:use-module (gnu packages polkit)
   #:use-module (gnu packages pkg-config)
   #:use-module (gnu packages python)
+  #:use-module (gnu packages w3m)
   #:use-module (gnu packages xml)
   #:use-module (gnu packages xdisorg)
   #:use-module (gnu packages xorg))
@@ -62,23 +64,61 @@
 (define-public xdg-utils
   (package
     (name "xdg-utils")
-    (version "1.0.2")
+    (version "1.1.1")
     (source
       (origin
         (method url-fetch)
           (uri (string-append
                  "https://portland.freedesktop.org/download/xdg-utils-"
-                 version ".tgz"))
+                 version ".tar.gz"))
           (sha256
             (base32
-             "1b019d3r1379b60p33d6z44kx589xjgga62ijz9vha95dg8vgbi1"))))
+             "09a1pk3ifsndc5qz2kcd1557i137gpgnv3d739pv22vfayi67pdh"))))
     (build-system gnu-build-system)
+    (native-inputs
+     `(("docbook-xsl" ,docbook-xsl)
+       ("docbook-xml" ,docbook-xml-4.1.2)
+       ("libxslt" ,libxslt)
+       ("w3m" ,w3m)
+       ("xmlto" ,xmlto)))
     (propagated-inputs
      `(("xprop" ,xprop) ; for Xfce detecting
        ("xset" ,xset))) ; for xdg-screensaver
     (arguments
-     `(#:tests? #f)) ; no check target
-    (home-page "http://portland.freedesktop.org/")
+     `(#:tests? #f   ; no check target
+       #:phases
+       (modify-phases %standard-phases
+         (add-after 'unpack 'patch-hardcoded-paths
+           (lambda _
+             (substitute* "scripts/xdg-mime.in"
+               (("/usr/bin/file") (which "file")))
+             (substitute* "scripts/xdg-open.in"
+               (("/usr/bin/printf") (which "printf")))
+             #t))
+         (add-before 'build 'locate-catalog-files
+           (lambda* (#:key inputs #:allow-other-keys)
+             (let ((xmldoc (string-append (assoc-ref inputs "docbook-xml")
+                                          "/xml/dtd/docbook"))
+                   (xsldoc (string-append (assoc-ref inputs "docbook-xsl")
+                                          "/xml/xsl/docbook-xsl-"
+                                          ,(package-version docbook-xsl))))
+               (for-each (lambda (file)
+                           (substitute* file
+                             (("http://.*/docbookx\\.dtd")
+                              (string-append xmldoc "/docbookx.dtd"))))
+                         (find-files "scripts/desc" "\\.xml$"))
+               (substitute* "scripts/Makefile"
+                 ;; Apparently `xmlto' does not bother to looks up the stylesheets
+                 ;; specified in the XML, unlike the above substitition. Instead it
+                 ;; uses a hard-coded URL. Work around it here, but if this is
+                 ;; common perhaps we should hardcode this path in xmlto itself.
+                 (("\\$\\(XMLTO\\) man")
+                  (string-append "$(XMLTO) -x " xsldoc
+                                 "/manpages/docbook.xsl man")))
+               (setenv "STYLESHEET"
+                       (string-append xsldoc "/html/docbook.xsl"))
+               #t))))))
+    (home-page "https://www.freedesktop.org/wiki/Software/xdg-utils/")
     (synopsis "Freedesktop.org scripts for desktop integration")
     (description "The xdg-utils package is a set of simple scripts that
 provide basic desktop integration functions in the framework of the
diff --git a/gnu/packages/games.scm b/gnu/packages/games.scm
index 31ba037af0..18ea6148c8 100644
--- a/gnu/packages/games.scm
+++ b/gnu/packages/games.scm
@@ -27,6 +27,7 @@
 ;;; Copyright © 2017 Adonay "adfeno" Felipe Nogueira <https://libreplanet.org/wiki/User:Adfeno> <adfeno@openmailbox.org>
 ;;; Copyright © 2017 Arun Isaac <arunisaac@systemreboot.net>
 ;;; Copyright © 2017 Tobias Geerinckx-Rice <me@tobias.gr>
+;;; Copyright © 2017 nee <nee-git@hidamari.blue>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -116,6 +117,8 @@
   #:use-module (gnu packages messaging)
   #:use-module (gnu packages upnp)
   #:use-module (gnu packages wxwidgets)
+  #:use-module (gnu packages bison)
+  #:use-module (gnu packages flex)
   #:use-module (guix build-system gnu)
   #:use-module (guix build-system haskell)
   #:use-module (guix build-system python)
@@ -2849,6 +2852,7 @@ safety of the Chromium vessel.")
                       ,(string-append "PREFIX=" %output)
                       "GNOME_PREFIX=$(PREFIX)"
                       "COMPLETIONDIR=$(PREFIX)/etc/bash_completion.d")
+       #:parallel-build? #f             ;fails on some systems
        #:tests? #f                      ;No tests
        #:phases (modify-phases %standard-phases
                   (delete 'configure)   ;no configure phase
@@ -3169,7 +3173,7 @@ throwing people around in pseudo-randomly generated buildings.")
 (define-public hyperrogue
   (package
     (name "hyperrogue")
-    (version "9.4c")
+    (version "9.4g")
     ;; When updating this package, be sure to update the "hyperrogue-data"
     ;; origin in native-inputs.
     (source (origin
@@ -3180,7 +3184,7 @@ throwing people around in pseudo-randomly generated buildings.")
                     "-src.tgz"))
               (sha256
                (base32
-                "1ri5fllnhqjm3dlnl1xbb9mlv79iigc940vbvcnk0v5k6p58pavq"))))
+                "09j9gnx701x28zfkrv3rjqlr56p89hyxk78gkpmmdfjgcq076pc2"))))
     (build-system gnu-build-system)
     (arguments
      `(#:tests? #f ; no check target
@@ -3235,14 +3239,14 @@ throwing people around in pseudo-randomly generated buildings.")
                           (string-append
                            "hyperrogue"
                            (string-join (string-split ,version #\.) "")
-                           "-win/sounds/credits.txt") "-d" sounds))
+                           "/sounds/credits.txt") "-d" sounds))
                 ;; Extract sounds and music into sounds directory.
                 (zero?
                  (system* "unzip" "-j" data
                           (string-append
                            "hyperrogue"
                            (string-join (string-split ,version #\.) "")
-                           "-win/*.ogg") "-d" sounds)))))))))
+                           "/*.ogg") "-d" sounds)))))))))
     (native-inputs
      `(("hyperrogue-data"
         ,(origin
@@ -3254,7 +3258,7 @@ throwing people around in pseudo-randomly generated buildings.")
              "-win.zip"))
            (sha256
             (base32
-             "1cyyrsnrixygg3zyz97hpsm6jzwbhydiwk3kl0lm7qjnw2nzkhhh"))))
+             "1r57db4hm7fjcd27p8b6cdsnq2cgkym2kp9lrw7ha2asdf8w6gkb"))))
        ("unzip" ,unzip)))
     (inputs
      `(("font-dejavu" ,font-dejavu)
@@ -3807,3 +3811,73 @@ utter witty remarks about their surroundings, the various inhabitants of their
 underwater realm quarrel among themselves or comment on the efforts of your
 fish.  The whole game is accompanied by quiet, comforting music.")
     (license license:gpl2+)))
+
+(define-public crawl
+  (package
+    (name "crawl")
+    (version "0.19.5")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (list
+             ;; Older releases get moved into a versioned directory
+             (string-append "http://crawl.develz.org/release/"
+                            (version-major+minor version) "/stone_soup-"
+                            version "-nodeps.tar.xz")
+             ;; Only the latest release is in this directory
+             (string-append "http://crawl.develz.org/release/stone_soup-"
+                            version "-nodeps.tar.xz")))
+       (sha256
+        (base32
+         "00yl2lb2shglxlxzpyk99zvglfx4amjybqwnzdcasvbiggb4cj18"))))
+    (build-system gnu-build-system)
+    (inputs
+     `(("lua51" ,lua-5.1)
+       ("ncurses" ,ncurses)
+       ("sqlite" ,sqlite)
+       ("zlib" ,zlib)))
+    (native-inputs
+     `(("bison" ,bison)
+       ("flex" ,flex)
+       ("perl" ,perl)
+       ("pkg-config" ,pkg-config)))
+    (arguments
+     '(#:make-flags
+       (let* ((sqlite (assoc-ref %build-inputs "sqlite"))
+              (out (assoc-ref %outputs "out")))
+         (list (string-append "SQLITE_INCLUDE_DIR=" sqlite "/include")
+               (string-append "prefix=" out)
+               "SAVEDIR=~/.crawl"
+               ;; TODO: build graphical client
+               "TILES="
+               ;; don't build any bundled dependencies
+               "BUILD_LUA="
+               "BUILD_SQLITE="
+               "BUILD_ZLIB="
+               "-Csource"))
+       #:phases
+       (modify-phases %standard-phases
+         (delete 'configure)
+         (delete 'check)
+         ;; Test cases require the source to be rebuild with the -DDEBUG define.
+         ;; Do 'check before 'build to avoid a 3rd build on make install.
+         (add-before 'build 'check
+           (lambda* (#:key inputs outputs make-flags #:allow-other-keys)
+             (setenv "HOME" (getcwd))
+             ;; Fake a terminal for the test cases.
+             (setenv "TERM" "xterm-256color")
+             (zero? (apply system* "make" "debug" "test"
+                           (format #f "-j~d" (parallel-job-count))
+                           make-flags)))))))
+    (synopsis "Roguelike dungeon crawler game")
+    (description "Dungeon Crawl Stone Soup is a roguelike adventure through
+dungeons filled with dangerous monsters in a quest to find the mystifyingly
+fabulous Orb of Zot.")
+    (home-page "https://crawl.develz.org")
+    (license (list license:gpl2+
+                   license:bsd-2
+                   license:bsd-3
+                   license:cc0
+                   license:expat
+                   license:zlib
+                   license:asl2.0))))
diff --git a/gnu/packages/gnome.scm b/gnu/packages/gnome.scm
index 8db53f109a..96dcbda72e 100644
--- a/gnu/packages/gnome.scm
+++ b/gnu/packages/gnome.scm
@@ -714,7 +714,7 @@ update-desktop-database: updates the database containing a cache of MIME types
 (define-public adwaita-icon-theme
   (package (inherit gnome-icon-theme)
     (name "adwaita-icon-theme")
-    (version "3.22.0")
+    (version "3.24.0")
     (source (origin
               (method url-fetch)
               (uri (string-append "mirror://gnome/sources/" name "/"
@@ -722,7 +722,7 @@ update-desktop-database: updates the database containing a cache of MIME types
                                   name "-" version ".tar.xz"))
               (sha256
                (base32
-                "1dyw8mm72wfpkn83vdqr0ifv5yhy565jhxrcjsd83nc7c3igd2y1"))))
+                "0ai73gs44yyw276xag6db0rlpvncy23qplp4girm80ilpprrzxyc"))))
     (native-inputs
      `(("gtk-encode-symbolic-svg" ,gtk+ "bin")))))
 
@@ -1848,7 +1848,7 @@ libraries written in C.")
 (define-public vte
   (package
     (name "vte")
-    (version "0.46.1")
+    (version "0.48.2")
     (source (origin
               (method url-fetch)
               (uri (string-append "mirror://gnome/sources/" name "/"
@@ -1856,22 +1856,15 @@ libraries written in C.")
                                   name "-" version ".tar.xz"))
               (sha256
                (base32
-                "1ipmnfazvhzjp5pjw90mmxbkizivnh7gnlqqml94lw2rqa5wy048"))))
+                "14060d5rmjjmxaknrabhnsjwxni5wa3crg61mqxv8f7yxl0v6y62"))))
     (build-system gnu-build-system)
-    (arguments
-     ;; XXX: fails to compile tests with the default flags.
-     ;; vteconv.cc:774:40:
-     ;;    error: missing sentinel in function call [-Werror=format=]
-     ;;    g_test_init (&argc, &argv, NULL);
-     ;;
-     ;; cc1plus: some warnings being treated as errors
-     '(#:configure-flags '("CXXFLAGS=-Wformat=0")))
     (native-inputs
      `(("pkg-config" ,pkg-config)
        ("intltool" ,intltool)
        ("vala" ,vala)
        ("gobject-introspection" ,gobject-introspection)
        ("glib" ,glib "bin") ; for glib-genmarshal, etc.
+       ("gperf" ,gperf)
        ("xmllint" ,libxml2)))
     (propagated-inputs
      `(("gtk+" ,gtk+)                             ;required by vte-2.91.pc
@@ -2440,7 +2433,7 @@ more fun.")
 (define-public gnome-terminal
   (package
     (name "gnome-terminal")
-    (version "3.22.1")
+    (version "3.24.1")
     (source
      (origin
        (method url-fetch)
@@ -2449,7 +2442,7 @@ more fun.")
                            name "-" version ".tar.xz"))
        (sha256
         (base32
-         "1m5h3ck7wcvq1kfap05jwhnbpp3kmikc2qy822gnsbdjdqrm41xh"))))
+         "1q303bljcr06w3ra737kq1hpjda45wk16kmrixxwldf3zkk2dgx7"))))
     (build-system glib-or-gtk-build-system)
     (arguments
      '(#:configure-flags
@@ -5243,7 +5236,7 @@ files.")
 (define-public baobab
   (package
     (name "baobab")
-    (version "3.22.1")
+    (version "3.24.0")
     (source (origin
               (method url-fetch)
               (uri (string-append
@@ -5252,7 +5245,7 @@ files.")
                     name "-" version ".tar.xz"))
               (sha256
                (base32
-                "1zwpzj6hbvcyw1ymqzn3zw8w4h29ad7411crbkbh71c8jwbwpssv"))))
+                "0gzwzn8p0agidjq3wnkxcsny6jhqph3yqscqjqd7blgkz5nyk02r"))))
     (build-system glib-or-gtk-build-system)
     (native-inputs
      `(("intltool" ,intltool)
diff --git a/gnu/packages/gnunet.scm b/gnu/packages/gnunet.scm
index 7bc17ad06a..44d6129897 100644
--- a/gnu/packages/gnunet.scm
+++ b/gnu/packages/gnunet.scm
@@ -5,7 +5,7 @@
 ;;; Copyright © 2015 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2016 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2016 Mark H Weaver <mhw@netris.org>
-;;; Copyright © 2016, 2017 ng0 <contact.ng0@cryptolab.net>
+;;; Copyright © 2016, 2017 ng0 <ng0@no-reply.pragmatique.xyz>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -184,14 +184,14 @@ and support for SSL3 and TLS.")
 (define-public gnurl
   (package
    (name "gnurl")
-   (version "7.53.1")
+   (version "7.54.0")
    (source (origin
             (method url-fetch)
             (uri (string-append "https://gnunet.org/sites/default/files/"
                                 name "-" version ".tar.bz2"))
             (sha256
              (base32
-              "1ah2304cm6y7d201vdph170mrwxmg6r72v2zsxzjn0jk68d8kb6d"))))
+              "1ww346cdsxln6iq158a4wm38bmicg5wspd2c83gnqf1glx22hza0"))))
    (build-system gnu-build-system)
    (outputs '("out"
               "doc"))                             ; 1.5 MiB of man3 pages
diff --git a/gnu/packages/gnuzilla.scm b/gnu/packages/gnuzilla.scm
index bfb0f1eb41..efe63adb4d 100644
--- a/gnu/packages/gnuzilla.scm
+++ b/gnu/packages/gnuzilla.scm
@@ -31,10 +31,10 @@
   #:use-module (guix download)
   #:use-module (guix utils)
   #:use-module (guix build-system gnu)
+  #:use-module (gnu packages autotools)
   #:use-module (gnu packages base)
   #:use-module (gnu packages databases)
   #:use-module (gnu packages glib)
-  #:use-module (gnu packages gstreamer)
   #:use-module (gnu packages gtk)
   #:use-module (gnu packages gnome)
   #:use-module (gnu packages libcanberra)
@@ -194,7 +194,7 @@ in the Mozilla clients.")
 (define-public nss
   (package
     (name "nss")
-    (version "3.30")
+    (version "3.30.2")
     (source (origin
               (method url-fetch)
               (uri (let ((version-with-underscores
@@ -205,9 +205,10 @@ in the Mozilla clients.")
                       "nss-" version ".tar.gz")))
               (sha256
                (base32
-                "1agkkwb51si4raw46p44vl3d0l7wzvdjcblpcdjjz6aymq6h1h58"))
+                "096frzvyp3z257x84rxknscfgsbavzh2a0gyibx7kvmw4vzpfjhd"))
               ;; Create nss.pc and nss-config.
               (patches (search-patches "nss-pkgconfig.patch"
+                                       "nss-disable-long-b64-tests.patch"
                                        "nss-increase-test-timeout.patch"))))
     (build-system gnu-build-system)
     (outputs '("out" "bin"))
@@ -301,10 +302,10 @@ standards.")
     (license license:mpl2.0)))
 
 (define (mozilla-patch file-name changeset hash)
-  "Return an origin for CHANGESET from the mozilla-esr45 repository."
+  "Return an origin for CHANGESET from the mozilla-esr52 repository."
   (origin
     (method url-fetch)
-    (uri (string-append "https://hg.mozilla.org/releases/mozilla-esr45/raw-rev/"
+    (uri (string-append "https://hg.mozilla.org/releases/mozilla-esr52/raw-rev/"
                         changeset))
     (sha256 (base32 hash))
     (file-name file-name)))
@@ -312,7 +313,7 @@ standards.")
 (define-public icecat
   (package
     (name "icecat")
-    (version "45.7.0-gnu1")
+    (version "52.0.2-gnu1")
     (source
      (origin
       (method url-fetch)
@@ -321,77 +322,162 @@ standards.")
                           "/" name "-" version ".tar.bz2"))
       (sha256
        (base32
-        "1mn73liylqzxk441f28wk326yglqs8zcwqs4zz51s8i2id2jsnv3"))
+        "0asaba04y6rwc7nx898p89jdxkbnsb3dxjvpdi8xb1rbgyms80c9"))
       (patches
        (list
         (search-patch "icecat-avoid-bundled-libraries.patch")
-        (search-patch "icecat-binutils.patch")
-        (mozilla-patch "icecat-CVE-2017-5398-pt01.patch" "1a39a54b5fea" "0k3sbf2w2yng2rpv6wl9zrm5cbsgq3pslr19xwrk8sk753as79fp")
-        (mozilla-patch "icecat-CVE-2017-5402.patch"      "9828c3bb7b73" "0zgks0v9sqhwwkmry4daswvjwk6aqln6abx0iac1vwqqpg6swff6")
-        (mozilla-patch "icecat-CVE-2017-5398-pt02.patch" "fa3268a1147e" "1jyd1hvp42pz5l15agmb1jhw74b38x8xnj9ih5v4pskv41bgmyg5")
-        (mozilla-patch "icecat-CVE-2017-5400.patch"      "347c10e4d6d1" "1w6yrm97l477q4ripbj0nimc87p4jscabvihpncxqbq9xzc4km7p")
-        (mozilla-patch "icecat-CVE-2017-5410.patch"      "fe4a2cda54ad" "0spcs93hpz13d8670jgvww80f0ynrbhwbh62fkv27lpr6wmqwqh1")
-        (mozilla-patch "icecat-CVE-2017-5401.patch"      "c38f8546be5f" "1sa22w9kzgynsn4c6zh4d66byskk5kffzbvlzrhyzvqjddypf9p8")
-        (mozilla-patch "icecat-CVE-2017-5398-pt03.patch" "41c80ecafa99" "0r33arr5wcgl00zgncasiyl65bmm6jy45clxnbb75nzjmsd1zx1s")
-        (mozilla-patch "icecat-CVE-2017-5405.patch"      "381552c888b4" "1sjhh390cx1jqx74lxk6qd8f8ccppqgagqfhc9pnbm2m67hxvkj9")
-        (mozilla-patch "icecat-CVE-2017-5407.patch"      "4ba337cdb998" "0vyknizid2z9nvl31m08c7fknizhv8dh8m54apm39k8lx77vf70p")
-        (mozilla-patch "icecat-CVE-2017-5398-pt04.patch" "886650fac531" "18fsr5dmav96ja0dah7mj34n8mjpckp0bbc32zjyaj5qx0m4h5cw")
-        (mozilla-patch "icecat-CVE-2017-5409.patch"      "0a22becb23cd" "19fshrq4qkj5s0mjrads6by84gy7rsq3k57gha6sw6rvx8chjaz6")
-        (mozilla-patch "icecat-CVE-2017-5398-pt05.patch" "a0ead6ef09eb" "1hpsq81hhhq2a2dcq2dfndiwx93vvp5rfq0cgv6kwk2bsrq77wqq")
-        (mozilla-patch "icecat-CVE-2017-5398-pt06.patch" "d3fede027d06" "1aw02p367cm0ayijdiiawlb7qhab6jwqwkakj317yd1cjnmkalwr")
-        (mozilla-patch "icecat-CVE-2017-5398-pt07.patch" "ffca0f060bb4" "0qwisfp7idjj5nc1vp1afrf5lj66l2gp7rllkjmrqpz6cyfc708v")
-        (mozilla-patch "icecat-CVE-2017-5398-pt08.patch" "4aa65b44dcb9" "07j6dz2b7hp1bkfvkxwgpn2wc3hqrgjgwpaz96fcpz8yadg2fssw")
-        (mozilla-patch "icecat-bug-1318914.patch"        "30e2382d800f" "0w8zky5i7zc5q943x37rdvi4wbcing0q7w9fcgvnnh5li2sbrsy8")
-        (mozilla-patch "icecat-CVE-2017-5408.patch"      "403d2300adc2" "06r4j48rc1fd9gvmvqy68mlqah5xfxpkvwmxk0gnqc364kpq9slk")
-        (mozilla-patch "icecat-CVE-2017-5398-pt09.patch" "546ab5e99568" "05rdb9bm3n4lj0zq5a95xnwsb0vzirb9mbc2wf9xbi4xlamsgvvw")
-        (mozilla-patch "icecat-bug-1311380.patch"        "ef6eeb7f8846" "1w19is5blbrwf3wlmy6wzgabih8sxp2kmkffqcj2g4jypfwyqn73")
-        (mozilla-patch "icecat-CVE-2017-5398-pt10.patch" "eec69810d80e" "1r20abhw7b38igsrdpkhcfwx9i9gmcxikv4y3sjr4wkbp684f7av")
-        (mozilla-patch "icecat-CVE-2017-5398-pt11.patch" "fec35ce6e68b" "1imdfrs8dxz44rhsmvydh29w5j64cij6g5ggrmhvz3386xvlil2v")
-        (mozilla-patch "icecat-CVE-2017-5398-pt12.patch" "725e2a217722" "06gfhi2ich279rjnxi15fb4igimsxnv5w6bx4g91js8wbvp2r3v0")
-        (mozilla-patch "icecat-CVE-2017-5398-pt13.patch" "d905a2e3a4d9" "1ibxi2s0czj47b739zmmjzbln8lpn27hdg4b17w58vhbhzkq31cx")
-        (mozilla-patch "icecat-CVE-2017-5398-pt14.patch" "0032560ae945" "0md3p5cix6nzbj5m199awc9gk52pygy5s9lx3a38vh3xvd92lsbj")
-        (mozilla-patch "icecat-CVE-2017-5398-pt15.patch" "91dda1e79ad8" "0b5h8fhagczfqkdgby982w6qgkw9y11zxxpdbn89rwmjpyp9nghx")
-        (mozilla-patch "icecat-CVE-2017-5404.patch"      "556dd9e4a9e3" "0mbdx4xn1xs67n47ys9m42lc5ny96rz21ala848yajpdlxsz680g")
-        (mozilla-patch "icecat-bug-1341137-pt1.patch"    "e86e0423dad1" "0dk1v7lcs61nx76qxcibha3ygqri15ldcvwwsrsayff9fq6k0v4y")
-        (mozilla-patch "icecat-bug-1341137-pt2.patch"    "9aebee8b8cb9" "0m7p5iprhhwdv89aqqg7fla5szw6v7x2sll4ns0zg60pk4vm6izq")
-        (mozilla-patch "icecat-bug-1341137-pt3.patch"    "69f3d44bdb48" "1ad7rw6nmg3c49ylqxlqqkb6cm2f0ygfzrigs6b60a2zkjqhbl0h")
-        (mozilla-patch "icecat-bug-1341137-pt4.patch"    "22546e2cee64" "0gbwxa3p7qkq53hwnvxcqhx8h34qmnjdxy0h3ajik4mw76vrna9s")
-        (mozilla-patch "icecat-bug-1341137-pt5.patch"    "e5083d8a855a" "1247vbpqzf007nigbxxqd6nwgr1dxd4p8cd0dr45afqh19vhlapj")
-        (mozilla-patch "icecat-bug-1339122.patch"        "b0d156c7445e" "026jp5bb565yvhkmmicgygcn1lmak85p0466yl1vnjlx1rc8n724")
-        (mozilla-patch "icecat-bug-1319087.patch"        "9cd44507fd65" "0mcfvby53r2150libazgrgaqrdyvl0g6cr1f01dsya3cgmc9mkcn")
-        (mozilla-patch "icecat-bug-1342661.patch"        "d449995ef7d9" "1kz8k2jxvhqpjgrsj7r0kqq79036lrkfnx5pvdnsl59np9128j81")
-        (mozilla-patch "icecat-bug-1343261.patch"        "9b5374019b58" "0v5w50r5ys4jjy1lpks280cq8paw7wdy9mrk7szzq7nlcxz90is7")
-        (mozilla-patch "icecat-bug-1343552-pt1.patch"    "08bc7a3330e4" "1hsvffscqc4zflni866ilylgi3a13wz0n882z85xplbhwhc9lcfj")
-        (mozilla-patch "icecat-bug-1343552-pt2.patch"    "8c61ebe37f1b" "1fjsr6bzfyd1zqzz2pglwh2ckys95h21wy3j4rlwkz66057z53qq")
-        (mozilla-patch "icecat-bug-1340718.patch"        "bfa75fc20c2b" "08gksd06lwbb5ykdrk9gh2cb9bximwxhbxl3rprz64jj2bnmd3dq")
-        (mozilla-patch "icecat-bug-1345461.patch"        "bcd5e51251dd" "1ms2ad8j04lz761cvdwi9rj5qv3qbjmg0zwyp3fykcf01a323ygd")
-        (mozilla-patch "icecat-bug-1343505.patch"        "290f10412f92" "1dsj22fkz60zfa6isnxj54clg32dwzapwh5f1vz6jsin9r67ik2p")
-        (mozilla-patch "icecat-bug-1346648.patch"        "9369ede30cc1" "1wrdn2aixbzifz7wyqnfi65gaiva8i746pi53z6w62lmn1hwd3ji")
-        (mozilla-patch "icecat-bug-1347979.patch"        "4ae2261bfab0" "1yi3jicwjy7w8f0sv5di4rx05bfpkhcwj3r6dhl5315yz4ifqy30")
-        (mozilla-patch "icecat-bug-1343795.patch"        "dcf468969700" "0syfq35s2r86ajmnqsxlfanvxd9ax57qkfmxpkvmk447s3mxsk08")
-        (mozilla-patch "icecat-bug-1347168.patch"        "5a6390274b64" "1lg5px4sncalh82y61ni9rlg50d83jmmrrvn0944x4zfrzlfaz8x")
-        (mozilla-patch "icecat-bug-1341096.patch"        "64158495e5ae" "1lyh8m159hhzrxj5hr0yib2sb8rkd20qxpykrf398v18s3yc08cx")
-        (mozilla-patch "icecat-bug-1346654.patch"        "f359ec604627" "0j6rzbnzlz8x9sj2r79d1zr4p89c5zq7y49xa4kn6am5ay3ws0ri")
-        (mozilla-patch "icecat-bug-1344461.patch"        "6f14d2ef7981" "0n24hqvjj7vxqdvxhk38swnmvcv7h7vvn5invbidhv22m0qqzs2c")
-        (mozilla-patch "icecat-bug-1292534.patch"        "c709d4b36145" "18cdck3fr4a1ygszb6qk07g6fi3kv6i697pjfcipvqrk358qb0hq")
-        (mozilla-patch "icecat-bug-1336830.patch"        "18e355831dd5" "042487xhq9zkky3pxiqy1rpy69z0j20w0jnl7kwg2j1bzfbnniip")
-        (mozilla-patch "icecat-bug-1336832.patch"        "ebeb0b45a84b" "17ch2aqsrnkiwbnkf6x7a1cpi8jgfjhwr6wp0bsa89s8v1dax6w4")
-        (mozilla-patch "icecat-bug-1349946.patch"        "ccbecbe17a45" "19vwmhvqarpzai8mcq6i7szkrp1h9m8v5lyimkmmdlmagrivjw7f")
-        (mozilla-patch "icecat-bug-1350683.patch"        "00ed655efad1" "0nfk9345lshim8xl29qka5man73jgxcppv3pzfrgjhk97z7h6ifq")
-        (mozilla-patch "icecat-bug-1342823.patch"        "609145968cfe" "1y5kw8khzxnx5cbrv4zmdd1nzha85r3cmxn3inami9fx8vikxjq8")
-        (mozilla-patch "icecat-bug-1336828.patch"        "982cfe33c513" "0amj3qx5399mrdcqakvfn5pabp562i1s87a8zd65jyqs4mwgcjap")
-        (mozilla-patch "icecat-bug-1348894.patch"        "eed8086d0af7" "18p567nhj7nvh740fhh3l0mqx0b7370b45005j43ll08rf2nhygl")
-        (mozilla-patch "icecat-bug-1344467.patch"        "38664f88d8f5" "0zdkmiqjr6h1bfs4qw74p5bnw74kcx9fxr4mcnshpavv2gvc6dn4")
-        (mozilla-patch "icecat-bug-1350844.patch"        "c071fab59d05" "16hf5c4appca8vwxl5yvl5ig5bw8cb8hl8apvknsn5rdsjwjlrpr")
-        (mozilla-patch "icecat-bug-1352926.patch"        "8fade3eebca2" "165v18545g4br1j6nbbhq2h9098iqvqpbd54zmgwwk9c973qhp3c")
-        (mozilla-patch "icecat-bug-1343642.patch"        "6172686bf59c" "0iwihvx11am28cbmgg68llf3mr4ghrclimr51vms1nq9ji767wdb")
-        (mozilla-patch "icecat-bug-1349340.patch"        "260b50fb6d39" "0lq08bkj1ihhwmf0yhxcnvngzym222q3n66ql9fbda4n7prlfhzl")
-        (mozilla-patch "icecat-bug-1353088.patch"        "44a90ca714b9" "1rb27bnrm9a5nnwrsxx7z36yhhz8x6lv0df98jv1128zvd373blp")
-        (mozilla-patch "icecat-bug-1347617.patch"        "e40b00161221" "0nm6jqbkb6rdahzd39gnhmy1gwawa5jbd7i80c7g1igj3x8ab50y")
-        (mozilla-patch "icecat-bug-1278157.patch"        "a7803c36d797" "10l8jbqlmfkvi4jj0vhkl0a9vdsh3niy5rjr26br3633nyyr4747")
-        (mozilla-patch "icecat-bug-1348941.patch"        "4fe9b979b84d" "069rzn60vn90gcck2wakr6m83q0cy32x5r54ccia9nc26a01p6p5")
-        (mozilla-patch "icecat-bug-1347075.patch"        "a017569d3535" "1j7q02q2ybpfx9cr6dn9x27jva1d6dzs4pdxx2a1xmk5va03lrmq")
-        (mozilla-patch "icecat-bug-1333858.patch"        "413dc18f25c8" "0g1q1y22m5gds8p07nq5c8f84jc152x4sac40b17gawj1005n5v9")))
+        (mozilla-patch "icecat-CVE-2017-5443.patch"      "6daaaff9f1f6" "0jvb6y5fiwr13fyx58k49n81kv6h03vcch502g57y6nsx2wsqng6")
+        (mozilla-patch "icecat-bug-1319087.patch"        "82297fcc6f19" "02qcbg2r2smswgnwj7fs5bcrr3rlqbpsh2nmcbsjyblp5fk1ag36")
+        (mozilla-patch "icecat-CVE-2017-5429-pt01.patch" "dd526ebe7e58" "1rj0pz6iql59zrynz48njcfg8i0v55bjdndplss9wl37lfydl7ca")
+        (mozilla-patch "icecat-CVE-2017-5447-pt1.patch"  "3bc981f85a17" "0am9k3mii2r05lp6xpizxp356mb8xrbqs9kmx0wx5wyy08wjzmks")
+        (mozilla-patch "icecat-CVE-2017-5447-pt2.patch"  "4f752b0e5920" "183s5dwzd57b299grvyvn139fsp9am0smd3yb4shw8g0iwzz61nf")
+        (mozilla-patch "icecat-CVE-2017-5449.patch"      "1714eda3de9b" "0ncngdpzvffvpw4c1mi0dda5l02lwyil4rnq3i6salnwlrq9x32z")
+        (mozilla-patch "icecat-CVE-2017-5455.patch"      "b10922304d81" "0rglbavb8rx7hl53ksgypazz27263b1yn97gznpdsq89zhirfw3m")
+        (mozilla-patch "icecat-CVE-2017-5446.patch"      "d98de46f8f27" "040agykr4w4wsbi0xm3rrrjxk48iwz8l1hn11vfv45nzsx2f1hzq")
+        ;; The next patch is for CVE-2017-5436 in the bundled graphite2.
+        ;; TODO: apply additional fixes from our system graphite2 to the
+        ;; bundled copy, or upgrade it in place.
+        (mozilla-patch "icecat-CVE-2017-5436.patch"      "e6132f638311" "07w9pijx42psgmkj2i6i87lf30gl0yyb5caz6wz7fm8phi8wwy9p")
+        (mozilla-patch "icecat-bug-1342395.patch"        "0e0e8abe2153" "1xlnq2fd50kf0rz9dibz5vlaa9zj2pifjvky2fdykcan62xz75hy")
+        (mozilla-patch "icecat-bug-1342841.patch"        "623afac083f8" "1pv86j0dxdmi7g3rx4zqplz4gxq5lfyzpdssq83naypcxic6zafb")
+        (mozilla-patch "icecat-bug-1344644.patch"        "cac0735c228f" "0695f0hvxnzgcirgxx3axn5nhkywqxjcvnrlhg7jwfann4mnbsfn")
+        (mozilla-patch "icecat-bug-1322660.patch"        "9d6d60e64255" "0ds74ilhyc9qkkjgkm0xk7ay3926971rzwfh2avhhkfargn7idib")
+        (mozilla-patch "icecat-bug-1343330.patch"        "6f23bd449bc7" "1igz6yhx803hygf7cii8bchx7bfw1niq8s0nc5l9i5rb8ml2b7f0")
+        (mozilla-patch "icecat-bug-1346961.patch"        "3a2dc54cf986" "0dfp3s7d43zx3svajbkhvi73b71hhr7vrc9yz0iz37pykg40c4hn")
+        (mozilla-patch "icecat-bug-1318070.patch"        "a68d6d9b87d0" "1yqgkgv7i0xy5dm0pgg1cbav4qglsdk8brzcjcpfz65bmn1pqrhh")
+        (mozilla-patch "icecat-CVE-2017-5448.patch"      "6684a3c7f834" "0agyynvcjk28d7l2l4cqz67ddg9xw7ymiirb0npabd1si9zj27xb")
+        (mozilla-patch "icecat-bug-1336345.patch"        "590416f46ec8" "1q2svqjd735rickr9i3kdkd0la6ikdphhmzr19h1r84nrl6a87ia")
+        (mozilla-patch "icecat-bug-1336356.patch"        "00ba83ac39be" "1h6qsfv4r9mlc2ihjm9kmzi76aijdnnyx1g2r30ia87xha106pnk")
+        (mozilla-patch "icecat-bug-1342363.patch"        "10285b4a6b71" "0l2ww19y6qbarcp9brjgbpf4vi3k38r6ak8is5736vqz0c17dim0")
+        (mozilla-patch "icecat-bug-1343787.patch"        "28287b7f0938" "1w85s9rqh0dyfx6qn5plypbypz9casig03b6yiy9bpiq7ckrxz56")
+        (mozilla-patch "icecat-bug-1292803.patch"        "adbf7b59a405" "1l1p0b5rc05czk6kr3k3k99m1fkwphj2jrd092gdbib8q4m4cvzv")
+        (mozilla-patch "icecat-bug-1313869.patch"        "eba25396310b" "1ws0dr0kwclzbc2m0sihd3aqvbbg57ycia0fg6y294k6qipcxv38")
+        (mozilla-patch "icecat-bug-1141756-pt1.patch"    "f7c262517722" "0r1zzbxf47q5w8vcy402yin105ngam3csb2q7h7n8axm97307ykp")
+        (mozilla-patch "icecat-bug-1141756-pt2.patch"    "420396d5e26d" "0yv1pmpydzkirfwrxrgbw98dm4a9a4s0izha0wabrp4lb3655jv5")
+        (mozilla-patch "icecat-bug-1343210.patch"        "ed9521749d6f" "1j2zzi00qyqjgh15ingvl6f88zlk4imp31m5jmf7w5f9jqi5ly3k")
+        (mozilla-patch "icecat-bug-1342442.patch"        "775b6f85ef81" "00h9dgds7jv9n4cznj5qhh8liaf1b3wvnlqc2z7a3kj07ijllwzb")
+        (mozilla-patch "icecat-bug-1344527.patch"        "d4612b14c907" "1n3a0mp351a7xgvshm6688gh89hg0xci3y621zs2pyqsfm114366")
+        (mozilla-patch "icecat-CVE-2017-5442.patch"      "5f1aa2336998" "1y2marhrglc66vchd6z0jdmhg0pmkxp1cwim63bp9l6pj7lxyjma")
+        (mozilla-patch "icecat-CVE-2017-5430-pt01.patch" "512604631b23" "171nzxr4av4818d0fyg9hcsdxkai61sghl45xnsr2al34l28wsw3")
+        (mozilla-patch "icecat-CVE-2017-5430-pt02.patch" "16772200ad6f" "087j16rcbs5kgvpa096kd6jarwwwfrhwph54wzjn671wr1vnsvvd")
+        (mozilla-patch "icecat-CVE-2017-5441.patch"      "c744e9d57250" "0m70157lczf17hxb2pabsl3grhcjqallbdfpsd58q8q6fk99k6x3")
+        (mozilla-patch "icecat-CVE-2017-5433.patch"      "b4fc7a4cb5e0" "12q6mr5prpgqg5xnrww09qjm3jx2amb8zig62cd46ba8n9z2j9ab")
+        (mozilla-patch "icecat-CVE-2017-5429-pt02.patch" "21eac0b4fd2f" "1a6v0hwcc26gnlxygplc11dfzc8bykhh44j4gsz88kl5c5jqhlk9")
+        (mozilla-patch "icecat-CVE-2017-5432.patch"      "62df7046e959" "1qvxbpkf87g4vnl8hxqvwb1ydrpkqq3rbkivr8q4029rvgalf4rf")
+        (mozilla-patch "icecat-bug-1350599.patch"        "f6a978b2fcec" "0rkbbmw52mxgrmn1xny4jkn3slwb5jsqs4yr07ffhz7r801jy9iz")
+        (mozilla-patch "icecat-bug-1332839.patch"        "2ad0f87f5dba" "04458jidri521hgf3r63pl736zz4gmgv6b8spa32anfb7gryj8fy")
+        (mozilla-patch "icecat-bug-1337548.patch"        "29a1ad09a6ec" "0pld81bpc34w6g2ara54sx30msas55kwzr537pvxxc002lpvzs57")
+        (mozilla-patch "icecat-CVE-2017-5430-pt03.patch" "5dec7534760f" "1xh0y7srl7nznb6szpfiykd6r1ibyxrdvasc36w0chqjdmq7xr32")
+        (mozilla-patch "icecat-bug-1343851.patch"        "e104d53316d7" "1yhv3qvzzi3kr881ji1dnm8ydnr3snh2vzl3c4vdzmvrjx8q5rcb")
+        (mozilla-patch "icecat-bug-1345222.patch"        "864644fadcb0" "0qpplxyfn87bigzdkwlrhj9isd5gfafhjgqfckb239a09wwrblf3")
+        (mozilla-patch "icecat-bug-1348584.patch"        "7cee9ad555af" "0856bpa3n71a3y5m4gilcdb9ghb60p545xkv9zbr245r20mj32ds")
+        (mozilla-patch "icecat-bug-1346720.patch"        "6a597a9cd494" "091a5sanw3w3gl0jcmf8d60m59vwbh5v36vnar20m0hl7xrv4v7p")
+        (mozilla-patch "icecat-CVE-2017-5430-pt04.patch" "09693629803f" "18fhmsghq0232mhh8j10cy0a4979nmkbh43jlcyrg3l63l7795k4")
+        (mozilla-patch "icecat-CVE-2017-5430-pt05.patch" "2b8268ea97a9" "0l0f54krxdmqbgldikwjncxvn6irihcljldd3z039himrvplisjg")
+        (mozilla-patch "icecat-bug-1347700-pt1.patch"    "ee706896916c" "0m85x80y98c154hyis08kcy81kbw3v34na1v862vxzs939d3mc0n")
+        (mozilla-patch "icecat-bug-1347700-pt2.patch"    "08ecc2d92f81" "1s6411ccifw9l22hhmf32nhm8r5hbclnhy7jm2n228sqfr4h971g")
+        (mozilla-patch "icecat-bug-1337682.patch"        "15af6a323161" "1nxbwd0574gscnkxfyhzv3yqvxiccb2d0rmba9vi6i62646l2pd5")
+        (mozilla-patch "icecat-CVE-2017-5451.patch"      "d91260f0069a" "15w4rzz51hps2fr8djf5z1rzdwxshclk936mxv5anx1skkwms0y8")
+        (mozilla-patch "icecat-CVE-2017-5444.patch"      "7740cf7e121b" "1706mx4zmnib336p2wmfp9ncyl66lk2da82f28xvcw262mg1c8lw")
+        (mozilla-patch "icecat-bug-1347164-pt1.patch"    "b35a6d6dcdca" "077r0pns58fw3xd3qnbhib4q21vvw0aynpa8iyn1pycg8mppmd0f")
+        (mozilla-patch "icecat-bug-1347164-pt2.patch"    "a42fc05969b9" "1ijq8ccsk5k56h77sv5kqv48w7csj3vbakzq98awgbvypzfdyhss")
+        (mozilla-patch "icecat-bug-1347164-pt3.patch"    "f78ac1ac0a37" "0kj6jq482cqwyngy1kmb69zpq35xah8h33kml8i4l7andiyaq3zm")
+        (mozilla-patch "icecat-bug-1347164-pt4.patch"    "795a3d48a775" "18lw99hmrr93k95hk6v6bx5rcf22aa902x2yf5p6wxdqg56nc0zp")
+        (mozilla-patch "icecat-bug-1338699.patch"        "94ce63191069" "0rdivablincah3gbgl4wzjmqlraazivmr8bhqxdpy8dk0a6fvv4s")
+        (mozilla-patch "icecat-bug-1342301.patch"        "e640e758a7cd" "17f36vvf82n6shlaip7ji8qsy9861f9a5r79h000p3wb3bb7lbfs")
+        (mozilla-patch "icecat-bug-1342170.patch"        "df7ed78b7c0a" "1kq256i66hcm2k9d37i5ws354ksv3bbglmscdjv2v5f7wg3y967v")
+        (mozilla-patch "icecat-bug-1342634.patch"        "d72e56823bbb" "0c186d77lyyg0hjxw15d44rybw6yr5aw8g9m3311xfdn5wiygijb")
+        (mozilla-patch "icecat-bug-1348796-pt1.patch"    "cef01720769e" "0h57372lxanjs5zw9b3vwr2x36yz9gj73swyg50aqp13j4rcbpmy")
+        (mozilla-patch "icecat-bug-1348796-pt2.patch"    "7d3584b75f20" "1a4hvpsvn39832g54hsxhqs24cq8v4nd69jqskkgc1ybs09ncmr3")
+        (mozilla-patch "icecat-bug-1192800.patch"        "e56b0938ea0f" "1hlbxhjzj65s6p2v6f66zdfb3gw5yx77msgq5idsv9jip2w88mpq")
+        (mozilla-patch "icecat-bug-1309438.patch"        "1f30d97563c8" "0rvq729fg9j959ha9qvw5wv7r6vw70qvpy7ynifgqhgrpa749n70")
+        (mozilla-patch "icecat-bug-1315332.patch"        "66495c8d9459" "0vzlx8i0cidpymm6ar07h3yk63fxf64f0b2vb0pihd72h0jzd5s9")
+        (mozilla-patch "icecat-bug-1346439.patch"        "a9fcc2dc324a" "13991jijwa84yczkmc212s23w269r8b1a4yiygqgwaily29l1dc5")
+        (mozilla-patch "icecat-CVE-2017-5469.patch"      "3dcc5f5c2df4" "0b36m6rgxc05h39l6wkzi6dlmq9brcigk7xjrifs4786f0z564hz")
+        (mozilla-patch "icecat-CVE-2017-5430-pt06.patch" "ac0ca89b5a6b" "1646y9y2wmq8pxb081x3076dq9ana7hh5fxwbsnn17v5wqhi8gfb")
+        (mozilla-patch "icecat-CVE-2017-5467.patch"      "6ed26e6c1a09" "0r1n1dwb4l8xwlns0aifyka6mldb6cy2crhh2qkap64cpj3bzl9s")
+        (mozilla-patch "icecat-CVE-2017-5439.patch"      "2fde528ca7b6" "0iv0sjhnh7br0z3pcpk346wbj162ynacfk3p9309hg6kr1cd92fp")
+        (mozilla-patch "icecat-CVE-2017-5440.patch"      "d88bd03d1234" "1pls63djh4w5023ag3fwjk79cpx816ilgajl5l1qlqyacl8c0v4p")
+        (mozilla-patch "icecat-bug-1349987.patch"        "3282e8f6a121" "1dyc84h7v0l9gndmbiwfqk33f703zr3fv96mwbn58msdf20ma9l2")
+        (mozilla-patch "icecat-CVE-2017-5434.patch"      "ee0a7b55e470" "01vs4p56p0ii0fvmg0kn7gaz6gwf2kwmv6v4pa6v68hwxx1phaag")
+        (mozilla-patch "icecat-CVE-2017-5430-pt07.patch" "a4e1e04c88ee" "0q07qwzxf2iisrhknjbn1zksv2rr6qzzh6w8ibzlj1sqbdg3h852")
+        (mozilla-patch "icecat-bug-1335043.patch"        "a49419f75b9c" "0pkh5yimnj3p1sd2g9vndgcn11zdx6yhpa88s8vk7fqbs8gf1fz3")
+        (mozilla-patch "icecat-bug-1299500-pt01.patch"   "5fdd36b4400a" "1gdrsbf03wf9v90f1bd2sp9ac38a9lzpzfrv8l8f7gvy70acjxmb")
+        (mozilla-patch "icecat-bug-1299500-pt02.patch"   "34776df5ce44" "15mlf59ii0rk97j8mlf3wz1q0w28ma5mll47dvci6cv3dziai9f1")
+        (mozilla-patch "icecat-bug-1299500-pt03.patch"   "26189af0f504" "1wh1s2xd1w03zi5jdaagk6j5i8v9xsm9360xmv446wdraygkqbci")
+        (mozilla-patch "icecat-bug-1299500-pt04.patch"   "798a8fe17e7b" "0vlalanffq3paa7zab003v1d377x5pvcsy8nc8fr5pdlvi622jll")
+        (mozilla-patch "icecat-bug-1299500-pt05.patch"   "daf2e4f2bd5c" "1rxbjbyr1a6dxjb0qj6900g3kqjphir40pis4qcfl8q811y18jwk")
+        (mozilla-patch "icecat-bug-1299500-pt06.patch"   "1187091c3134" "0r8zz4zbglxg6sl0ybz9lyq1c5w2nqp0xcn2d3rz9bvyj8byqc7m")
+        (mozilla-patch "icecat-bug-1299500-pt07.patch"   "a908f2c2fe30" "1fvwy3fxfrdi9y8hmf4f9aa72i0g6s55s8cp0w22gllsl1f6gvyf")
+        (mozilla-patch "icecat-bug-1299500-pt08.patch"   "e95a26cf7a42" "0pd0kcn7dqd1gy1si85as5zzc96v7vq0v8n3g3gjzms5rdnk085l")
+        (mozilla-patch "icecat-bug-1299500-pt09.patch"   "d63f3b14e571" "0cqd7dal6prsrj7bn2d699idbq4fzjry9vqlbmm9dkyn5683sdy1")
+        (search-patch  "icecat-bug-1299500-pt10.patch") ; Adapted for GNU IceCat, based on:
+                                                        ;"08f2bc167ae8" "07d1i23ffvi74a5558bb0645vbrap6qlrpcwfyb7dm3llbfnfycy")
+        (mozilla-patch "icecat-bug-1299500-pt11.patch"   "263f27805689" "0nczkvyvlpdjif3xfvj7g2mfz6j06w99x2sblqfmqq6mwrlavpq0")
+        (mozilla-patch "icecat-CVE-2017-5456.patch"      "538e0b382cc2" "0wq2ywn4a7i4ypcx03hl23a4xx3lavz7y505m9kw43fx15r4070r")
+        (mozilla-patch "icecat-bug-1280079.patch"        "6fbcb6a4b91e" "0qcwz9js1bwlnwyv3vhkm0hvahd043lm2bijqsmm0jy20dbslga4")
+        (mozilla-patch "icecat-CVE-2017-5435.patch"      "a362e1205ba4" "127i4ybfb4dk5axp4dxcl7ag7zyx7b517myvs6q4yd8981d1jjd3")
+        (mozilla-patch "icecat-bug-1341960.patch"        "b24ce30e8cfa" "0a521wn8hbaliawmxs21b8wc1gkha8iih62j4zyrfg5rm7ff6p6s")
+        (mozilla-patch "icecat-CVE-2017-5454.patch"      "ac40d4a4e414" "0dnzz95vpq32bsh6hajk4hrcrxwd4w6m7kayl2iziryny86jgak2")
+        (mozilla-patch "icecat-CVE-2017-5429-pt03.patch" "e469af8e9ccc" "0yn8zqakr9yw0jvysxyc8if09kqf4fr5rq4p9qdkb1p81p4dpmp5")
+        (mozilla-patch "icecat-bug-1351094.patch"        "4c1383e76adc" "0wdldx88qabyhrwnnii44pggmfgqylzxy6ckwzgq86r2yipi4rsq")
+        (mozilla-patch "icecat-bug-1336527.patch"        "b9f53baeabb3" "0y1l641ffbr4i85p0wc1ir6bcsy6h94bchbfc7ppxfijva4fjgvd")
+        (mozilla-patch "icecat-bug-1345716.patch"        "2569af645a98" "1d6lx85ij90j6q6ixwp0h3w7y424yvkz0njsi0my727akbli5rsn")
+        (mozilla-patch "icecat-bug-1208957.patch"        "2b68880d8f6b" "1pl0vkv7clyjchi9kg4995z82sr8xv7cbz1kvsg1v66md6pmp4s4")
+        (mozilla-patch "icecat-bug-1208957.patch"        "bc646835442b" "0f29r5yvlb5w84nvvn6j9r9dq5314jgygjmsna3grzigpkb88gyj")
+        (mozilla-patch "icecat-bug-1347944.patch"        "47cb652ddc25" "0n7871958zwndwz53xvzwjv41v5ar1vxaam8kzr5dkbqmprddimx")
+        (mozilla-patch "icecat-bug-1347632.patch"        "7d8f7a52a108" "0gkbkzkz989j7pk3ia1rfvyjg3si8hnnadwkb2rw13qjxdzhx2zn")
+        (mozilla-patch "icecat-CVE-2017-5438.patch"      "154c93b9435b" "00f8lr5s8h68392bb45zi0xfgqrgfkdxbzwdypp10d89784fvjvd")
+        (mozilla-patch "icecat-bug-1347486.patch"        "15dbaf157058" "1mwgfnx1zsvhp0pgmc8577yw6lnf7g3ikdfj0r21fgffrn76bp69")
+        (mozilla-patch "icecat-bug-1218437.patch"        "e13692bfd5f5" "10jrbs26m8l1vchw6svssrb5h8p82acrcmkx92ybvv4qbaq2bcl0")
+        (mozilla-patch "icecat-bug-1345853.patch"        "5fa27dc4c4a3" "1sqqa4hir2bsnnwnlr34has62kpncmw6l9mylwprd09fxmzzgrd7")
+        (mozilla-patch "icecat-CVE-2017-5429-pt04.patch" "00c051cd38c7" "1d4aa4nqyjc01mg3jvdjjp7z05c2qhdjj85dhdrd9c18gfiyv4fi")
+        (mozilla-patch "icecat-bug-1349921.patch"        "c6897adc4037" "0acvcdy8awdmpz84243jzf82agrm73wqa198fjbns1p1v3s425z2")
+        (mozilla-patch "icecat-bug-1338623.patch"        "edcafd42dd52" "1xqgjy7a62jsyz1b5mibrcnd7zpb4gdaas0a6z5dwfvz52j4xa16")
+        (mozilla-patch "icecat-bug-1294799.patch"        "0617b074ec3d" "19h7dj44shvdzzj87svpv5q97cikxyxhiwfzf9rnqj1b7fw0xrdh")
+        (mozilla-patch "icecat-bug-1345049.patch"        "88466b911357" "16pgd13mw9a0snyhq6vxmjc7kr9mikvhazkgbc6vpykwi0i0z85b")
+        (mozilla-patch "icecat-bug-1339999.patch"        "b7cb8f8b0877" "0zv1kxcva699ahb9s36l4d9mlrkm0b7hmh6g1422j6iijn136vxb")
+        (mozilla-patch "icecat-bug-1350868.patch"        "ddd6c44790c0" "182ii4wsz2vdd1q4dszd5hka8i2n0ghmqk7l39bd02d3zfibhhvc")
+        (mozilla-patch "icecat-bug-1342360.patch"        "416681a239ef" "0ngs8xgmdhz9ag4dlrqhr0vmanqxr9q2vf16jpm3cimyc06zjxz4")
+        (mozilla-patch "icecat-CVE-2017-5429-pt05.patch" "a76e626ae6db" "0zn2j8fmhp7502kx1jhrvh85vsys5x6x6gw3v4gl0h8px354v6yw")
+        (mozilla-patch "icecat-CVE-2017-5429-pt06.patch" "0ce4196ab86e" "0isczy8261qz2zsdxax4j51gypz0gi39q7nfwxg88sl81kc5vym8")
+        (mozilla-patch "icecat-CVE-2017-5429-pt07.patch" "39da731d80ed" "0vswnv1hqa7r8iz6y5ja7i6w3cyq5xrcd66c1q29ac6n4gn7x338")
+        (mozilla-patch "icecat-CVE-2017-5430-pt08.patch" "1b148cf9c545" "0ilrib0c2c7mfycpz2hq3vrfdf6sf8lcdbfjk6r4xyxv54vh3lwk")
+        (mozilla-patch "icecat-bug-1325841.patch"        "74e9f13c554f" "0glzcgjsy71y78zaccn33w8djs96i6dd3gafyzkihnkpfddd5cij")
+        (mozilla-patch "icecat-CVE-2017-5445.patch"      "d7d87adfe186" "02p705si2j69ya8n5a916x58nycs07ja0sfpxrwl16f4n2plc91h")
+        (mozilla-patch "icecat-bug-1346424.patch"        "5ede402f494f" "0kbx8yn8ppv7099ic6nhw32f7h42pnwk6dpvb179ilw90ah902q7")
+        (mozilla-patch "icecat-CVE-2017-5430-pt09.patch" "da44c5cfab2e" "16i4dz5sfkhh3a0khrcf8zn5w20rkf4aqwygjj3cp4qhdh7wnr75")
+        (mozilla-patch "icecat-CVE-2017-5430-pt10.patch" "0f966927bd55" "07pkhc6l6ylwrzgfm7i1galrvjawqqrhvhk6jcw4b30sfhi0bxq1")
+        (mozilla-patch "icecat-CVE-2017-5429-pt08.patch" "f0f591f82cc0" "18p091503vpfpp4l3d7hkqj78zavv6qj1lynhlfx67zdp3xqcf8r")
+        (mozilla-patch "icecat-CVE-2017-5464.patch"      "1852dc0beba4" "1zdnkrsqjfv1q2jhj4829ypiwyg78n4jv54yn3b74vwcf5zvzx8m")
+        (mozilla-patch "icecat-bug-1083140.patch"        "6913f0537208" "0vaf61ryp0bzkz6l1w73alhglibbgm0jcgccxvvm43ni67pcxqbq")
+        ;; The patch commented out below updates the bundled tzdata,
+        ;; but we can't use it because it contains a GIT binary patch.
+        ;; TODO: Consider updating the bundled tzdata, or unbundling it.
+        ;; (mozilla-patch "icecat-bug-1343493.patch"       "35496444b380" "1wa79az7121xw078cgpczxavrqy0fsp4ib2nb69giha6acxcaqas")
+        (mozilla-patch "icecat-CVE-2017-5430-pt11.patch" "64495dfa29db" "0m7vklnwnaf7sw97m87bm4lb9pjmlh1vvrbaf1931db8nhd6m737")
+        (mozilla-patch "icecat-bug-1350783.patch"        "26cd34db3c14" "15vq3lrilg3n9j80cdjmk7xib2iq5gcx9ypq8xs7f5ya9ibasqlx")
+        (mozilla-patch "icecat-CVE-2017-5429-pt09.patch" "6cd77a0d7ac0" "0kxlbl5m3gffxqrv7ky3swsbyg1ykj0wjhlfl9amsb4g8gra3zkj")
+        (mozilla-patch "icecat-CVE-2017-5460-pt1.patch"  "a803be74843c" "1ywwakzjkfr714i9pfn152n86c6rp427chzdys8phdkcvp5d5p45")
+        (mozilla-patch "icecat-CVE-2017-5460-pt2.patch"  "73762c1392ae" "18jy9ccqvn6l6hznvq5xsqm1pc7i81svc2grgv21wfwg9sd6zwwh")
+        (mozilla-patch "icecat-bug-1337392-pt1.patch"    "4ab6d5c43036" "07pygzngssra9wnmqqrs24d6gc5kfh20fkzvpcasxh4f2hi21z9b")
+        (mozilla-patch "icecat-bug-1337392-pt2.patch"    "13f2d85da9a7" "1iwfz7dp5i93bhjspy4kyz0vqrl8x8ndg5kxdyzwb1b339xim9qy")
+        (mozilla-patch "icecat-CVE-2017-5429-pt10.patch" "7a30cddfcd54" "1773pijh6gi086l930cn1a0k7kvy7f3cnirfblw98sq7h9qfyy33")
+        (mozilla-patch "icecat-bug-1345873-pt1.patch"    "75cea353ad78" "14cig2y7d3p033hx3096gxzlqwgddq8d0ig0g3l8p1b0xwvvyryl")
+        (mozilla-patch "icecat-bug-1345873-pt2.patch"    "b08ef5a82f89" "0afz01jv850x09df85d7ycqkcdlafi4w2xi5k155lk2b92w8lhpj")
+        (mozilla-patch "icecat-bug-1340163.patch"        "f3f2a995a239" "1ydsj4ja475jscalkw6ggdxgbsp5l2mam5109k0y7c98abzqraxk")
+        (mozilla-patch "icecat-bug-1348174-pt1.patch"    "330904d6f0dc" "19wnp4d8481w86xkk78n7c7wrr99rq6cq3v09hd8am4n0mzwzaja")
+        (mozilla-patch "icecat-bug-1348174-pt2.patch"    "c61b99483c4b" "0mjsahi8ly24415ri2sylas6g0kb8wawi095idqiq019c3r7q9cq")
+        (mozilla-patch "icecat-bug-1348601.patch"        "1848bd238064" "1f5kadhn6w1rs26sdrcc3mq0zzlmmsm6ymqhshkzn57nrj6akm7b")
+        (mozilla-patch "icecat-bug-1345991.patch"        "2008a4b89d9a" "07fkg9r2rxbk362ckv2h8inhd2dadvzigshm6zsjfjs2fyzp95hp")
+        (mozilla-patch "icecat-bug-1344498-pt1.patch"    "9acd0103d67f" "1f0j667g05h9ydmc924cs8mzif1n7s56wixsgnyqc3s231dswhml")
+        (mozilla-patch "icecat-bug-1344498-pt2.patch"    "49aadb25b1ec" "0s618m802b1x5pyqh5mj1azaxch7ggxq9503b7mwhg90vz8qw7ki")
+        (mozilla-patch "icecat-bug-1344205.patch"        "34b453085dc0" "02h1bh24f9i5sm3my07m2q58cpzqfhagwwv11l9fidxcm9dmzmrd")
+        (mozilla-patch "icecat-bug-1349862.patch"        "864ff0c36b6b" "1i3wmigv982x9hzkfg25jhyvkynmar69x6cj6r4g9zkk5f5ypdh5")
+        (mozilla-patch "icecat-CVE-2017-5459.patch"      "5ec6fbedb420" "07flhha4rkjbry5590yr5by36ypb1k33qm3rzkbmw0vk5gyak8dp")
+        (mozilla-patch "icecat-CVE-2017-5465.patch"      "2b95de78a92c" "0vvq1fz84yyw7za929x6ki25paivlwd4ng1ddkcb2bw6da6yp12k")
+        (mozilla-patch "icecat-CVE-2017-5466.patch"      "a5ec5e70abf1" "1jjviyk6db8iccd7997mwmgs188fsyrzivap3ffjf8m6j4mf9cra")
+        (mozilla-patch "icecat-bug-1347646.patch"        "1b50711a46ce" "1i3505zzgf0mvg2405y2gzq36xc8ic2ga8w6d3n9kqryxj0mc7bh")))
       (modules '((guix build utils)))
       (snippet
        '(begin
@@ -423,6 +509,7 @@ standards.")
                       ;;
                       ;; TODO: Use system graphite2.
                       ;;
+                      "dom/devicestorage"  ; Removed in ESR 52.1, awkward to patch out
                       "modules/freetype2"
                       "modules/zlib"
                       "modules/libbz2"
@@ -449,9 +536,8 @@ standards.")
        ("dbus-glib" ,dbus-glib)
        ("gdk-pixbuf" ,gdk-pixbuf)
        ("glib" ,glib)
-       ("gstreamer" ,gstreamer)
-       ("gst-plugins-base" ,gst-plugins-base)
-       ("gtk+" ,gtk+-2)
+       ("gtk+" ,gtk+)
+       ("gtk+-2" ,gtk+-2)
        ("pango" ,pango)
        ("freetype" ,freetype)
        ("hunspell" ,hunspell)
@@ -465,6 +551,7 @@ standards.")
        ("libxcomposite" ,libxcomposite)
        ("libxt" ,libxt)
        ("libffi" ,libffi)
+       ("ffmpeg" ,ffmpeg)
        ("libvpx" ,libvpx)
        ("icu4c" ,icu4c)
        ("pixman" ,pixman)
@@ -476,14 +563,15 @@ standards.")
        ("sqlite" ,sqlite)
        ("startup-notification" ,startup-notification)
        ("unzip" ,unzip)
-       ("yasm" ,yasm)
        ("zip" ,zip)
        ("zlib" ,zlib)))
     (native-inputs
      `(("perl" ,perl)
        ("python" ,python-2) ; Python 3 not supported
        ("python2-pysqlite" ,python2-pysqlite)
+       ("yasm" ,yasm)
        ("pkg-config" ,pkg-config)
+       ("autoconf" ,autoconf-2.13)
        ("which" ,which)))
     (arguments
      `(#:tests? #f          ; no check target
@@ -495,17 +583,11 @@ standards.")
        ;; practice somehow.  See <http://hydra.gnu.org/build/378133>.
        #:validate-runpath? #f
 
-       #:configure-flags '("--enable-default-toolkit=cairo-gtk2"
-                           "--enable-pango"
+       #:configure-flags '("--enable-default-toolkit=cairo-gtk3"
                            "--enable-gio"
-                           "--enable-svg"
-                           "--enable-canvas"
-                           "--enable-mathml"
                            "--enable-startup-notification"
                            "--enable-pulseaudio"
-                           "--enable-gstreamer=1.0"
 
-                           "--disable-gnomevfs"
                            "--disable-gconf"
                            "--disable-gnomeui"
 
@@ -563,16 +645,6 @@ standards.")
                          #t))
               #t)))
          (add-after
-          'unpack 'remove-h264parse-from-blacklist
-          (lambda _
-            ;; Remove h264parse from gstreamer format helper blacklist.  It
-            ;; was put there to work around a bug in a pre-1.0 version of
-            ;; gstreamer.  See:
-            ;; https://www.mozilla.org/en-US/security/advisories/mfsa2015-47/
-            (substitute* "dom/media/gstreamer/GStreamerFormatHelper.cpp"
-              (("^  \"h264parse\",\n") ""))
-            #t))
-         (add-after
           'unpack 'use-skia-by-default
           (lambda _
             ;; Use the bundled Skia library by default, since IceCat appears
@@ -595,10 +667,11 @@ standards.")
             ;; calls to dlopen or PR_LoadLibrary, but that didn't seem to
             ;; work.  More investigation is needed.
             (substitute* "toolkit/library/moz.build"
-              (("^# This needs to be last")
-               "OS_LIBS += [
+              (("^# This library needs to be last" all)
+               (string-append "OS_LIBS += [
     'GL', 'gnome-2', 'canberra', 'Xss', 'cups', 'gssapi_krb5',
-    'gstreamer-1.0', 'gstapp-1.0', 'gstvideo-1.0' ]\n\n"))
+    'avcodec', 'avutil', 'pulse' ]\n\n"
+                              all)))
             #t))
          (replace
           'configure
@@ -615,6 +688,7 @@ standards.")
                             ,@configure-flags)))
               (setenv "SHELL" bash)
               (setenv "CONFIG_SHELL" bash)
+              (setenv "AUTOCONF" (which "autoconf")) ; must be autoconf-2.13
               (mkdir "../build")
               (chdir "../build")
               (format #t "build directory: ~s~%" (getcwd))
@@ -676,7 +750,16 @@ standards.")
                       (copy-file file (string-append icons "/icecat.png"))))
                   '("default16.png" "default22.png" "default24.png"
                     "default32.png" "default48.png" "content/icon64.png"
-                    "mozicon128.png" "default256.png")))))))))
+                    "mozicon128.png" "default256.png"))))))
+         ;; This fixes the file chooser crash that happens with GTK 3.
+         (add-after 'install 'wrap-program
+           (lambda* (#:key inputs outputs #:allow-other-keys)
+             (let* ((out (assoc-ref outputs "out"))
+                    (lib (string-append out "/lib"))
+                    (gtk (assoc-ref inputs "gtk+"))
+                    (gtk-share (string-append gtk "/share")))
+               (wrap-program (car (find-files lib "^icecat$"))
+                 `("XDG_DATA_DIRS" ":" prefix (,gtk-share)))))))))
     (home-page "https://www.gnu.org/software/gnuzilla/")
     (synopsis "Entirely free browser derived from Mozilla Firefox")
     (description
diff --git a/gnu/packages/gstreamer.scm b/gnu/packages/gstreamer.scm
index b3a2d575a7..c284a8d2b3 100644
--- a/gnu/packages/gstreamer.scm
+++ b/gnu/packages/gstreamer.scm
@@ -154,11 +154,7 @@ This package provides the core library and elements.")
                           name "-" version ".tar.xz"))
       (sha256
        (base32
-        "1dsyjf6rncsbg4rfj40cvf1wwpjj9h3j3c7bh4zp7jylnfv4blpn"))
-;      (patches
-;       (search-patches "gst-plugins-base-fix-test-on-32bit.patch"))
-      
-      ))
+        "1dsyjf6rncsbg4rfj40cvf1wwpjj9h3j3c7bh4zp7jylnfv4blpn"))))
     (build-system gnu-build-system)
     (outputs '("out" "doc"))
     (propagated-inputs
diff --git a/gnu/packages/guile.scm b/gnu/packages/guile.scm
index 207daa54e6..6d9f58c4ed 100644
--- a/gnu/packages/guile.scm
+++ b/gnu/packages/guile.scm
@@ -221,7 +221,7 @@ without requiring the source code to be rewritten.")
 (define-public guile-2.2
   (package (inherit guile-2.0)
     (name "guile")
-    (version "2.2.0")
+    (version "2.2.2")
     (replacement #f)
     (source (origin
               (method url-fetch)
@@ -229,7 +229,7 @@ without requiring the source code to be rewritten.")
                                   ".tar.lz"))
               (sha256
                (base32
-                "083vp6754dp4d5pvcy4bqvxq60cayf92v5slf5cgij8bnvixgyvr"))
+                "1dnh75h4rkx1zflpsngznkwcd6afn6zrc5x3xq7n946pm5bnx5bq"))
               (modules '((guix build utils)))
 
               ;; Remove the pre-built object files.  Instead, build everything
diff --git a/gnu/packages/hurd.scm b/gnu/packages/hurd.scm
index b5da4cb963..bd1eb4b085 100644
--- a/gnu/packages/hurd.scm
+++ b/gnu/packages/hurd.scm
@@ -39,6 +39,10 @@
   (string-append "mirror://gnu/gnumach/gnumach-"
                  version ".tar.gz"))
 
+(define (hurd-source-url version)
+  (string-append "mirror://gnu/hurd/hurd-"
+                 version ".tar.gz"))
+
 (define-public gnumach-headers
   (package
     (name "gnumach-headers")
@@ -113,8 +117,7 @@ communication.")
     (version "0.9")
     (source (origin
               (method url-fetch)
-              (uri (string-append "mirror://gnu/hurd/hurd-"
-                                  version ".tar.gz"))
+              (uri (hurd-source-url version))
               (sha256
                (base32
                 "1nw9gly0n7pyv3cpfm4mmxy4yccrx4g0lyrvd3vk2vil26jpbggw"))))
@@ -242,3 +245,44 @@ Hurd-minimal package which are needed for both glibc and GCC.")
     (description
      "GNU Mach is the microkernel upon which a GNU Hurd system is based.")
     (license gpl2+)))
+
+(define-public hurd
+  (package
+    (name "hurd")
+    (version "0.9")
+    (source (origin
+              (method url-fetch)
+              (uri (hurd-source-url version))
+              (sha256
+               (base32
+                "1nw9gly0n7pyv3cpfm4mmxy4yccrx4g0lyrvd3vk2vil26jpbggw"))
+              (patches (search-patches "hurd-fix-eth-multiplexer-dependency.patch"))))
+    (arguments
+     `(#:phases
+       (modify-phases %standard-phases
+         (add-before 'build 'pre-build
+                     (lambda _
+                       ;; Don't change the ownership of any file at this time.
+                       (substitute* '("daemons/Makefile" "utils/Makefile")
+                         (("-o root -m 4755") ""))
+                       #t)))
+       #:configure-flags (list (string-append "LDFLAGS=-Wl,-rpath="
+                                              %output "/lib")
+                          "--disable-ncursesw"
+                          "--without-libbz2"
+                          "--without-libz"
+                          "--without-parted")))
+    (build-system gnu-build-system)
+    (inputs `(("glibc-hurd-headers" ,glibc/hurd-headers)))
+    (native-inputs
+     `(("mig" ,mig)
+       ("perl" ,perl)))
+    (supported-systems %hurd-systems)
+    (home-page "https://www.gnu.org/software/hurd/hurd.html")
+    (synopsis "The kernel servers for the GNU operating system")
+    (description
+     "The Hurd is the kernel for the GNU system, a replacement and
+augmentation of standard Unix kernels.  It is a collection of protocols for
+system interaction (file systems, networks, authentication), and servers
+implementing them.")
+    (license gpl2+)))
diff --git a/gnu/packages/ibus.scm b/gnu/packages/ibus.scm
index 6c5537579e..04be3b0c3b 100644
--- a/gnu/packages/ibus.scm
+++ b/gnu/packages/ibus.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2015, 2016 Ricardo Wurmus <rekado@elephly.net>
+;;; Copyright © 2015, 2016, 2017 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2015 Andreas Enge <andreas@enge.fr>
 ;;; Copyright © 2016 Chris Marusich <cmmarusich@gmail.com>
 ;;;
@@ -135,7 +135,7 @@ may also simplify input method development.")
 (define-public ibus-libpinyin
   (package
    (name "ibus-libpinyin")
-   (version "1.7.2")
+   (version "1.9.0")
    (source (origin
              (method url-fetch)
              (uri (string-append "https://github.com/libpinyin/"
@@ -143,7 +143,7 @@ may also simplify input method development.")
              (file-name (string-append name "-" version ".tar.gz"))
              (sha256
               (base32
-               "080ixx5lih9lr78b061y67dqmiyc7ij87jl1sa26hhs1dr28ihka"))))
+               "0gly314z6zn2fv52jw0764k66ry97llk009bk1q1iwf6rr829v68"))))
    (build-system glib-or-gtk-build-system)
    (arguments
      `(#:phases
@@ -190,7 +190,7 @@ ZhuYin (Bopomofo) input method based on libpinyin for IBus.")
 (define-public libpinyin
   (package
     (name "libpinyin")
-    (version "1.2.0")
+    (version "2.0.0")
     (source (origin
               (method url-fetch)
               (uri (string-append
@@ -199,18 +199,18 @@ ZhuYin (Bopomofo) input method based on libpinyin for IBus.")
               (file-name (string-append name "-" version ".tar.gz"))
               (sha256
                (base32
-                "04didxd39vlry6nqy7xqynwc68ndajnhw334wahfmp7zjbbscs7p"))))
+                "17fibx9psrxfiznm4yw8klgbnh3ksyisx0pm1n59kxkrq61v8y0b"))))
     (build-system gnu-build-system)
     (arguments
      `(#:phases
        (modify-phases %standard-phases
          (add-before 'configure 'autogen
-          (lambda _ (zero? (system* "autoreconf" "-vif"))))
+           (lambda _ (zero? (system* "autoreconf" "-vif"))))
          (add-after 'unpack 'unpack-model
-          (lambda* (#:key inputs #:allow-other-keys)
-            (zero? (system* "tar" "-xvf"
-                            (assoc-ref inputs "model")
-                            "-C" "data")))))))
+           (lambda* (#:key inputs #:allow-other-keys)
+             (zero? (system* "tar" "-xvf"
+                             (assoc-ref inputs "model")
+                             "-C" "data")))))))
     (inputs
      `(("glib" ,glib)
        ("bdb" ,bdb)
@@ -218,10 +218,10 @@ ZhuYin (Bopomofo) input method based on libpinyin for IBus.")
         ,(origin
            (method url-fetch)
            (uri (string-append "mirror://sourceforge/libpinyin/"
-                               "models/model10.text.tar.gz"))
+                               "models/model14.text.tar.gz"))
            (sha256
             (base32
-             "0g489wqcfklxphhxpkh8i4qf9y8scmnmdbfrzdbrgf3rignbwyiw"))))))
+             "0qqk30nflj07zjhs231c95ln4yj4ipzwxxiwrxazrg4hb8bhypqq"))))))
     (native-inputs
      `(("pkg-config" ,pkg-config)
        ("autoconf" ,autoconf)
diff --git a/gnu/packages/icu4c.scm b/gnu/packages/icu4c.scm
index 2b51441002..9f465b1022 100644
--- a/gnu/packages/icu4c.scm
+++ b/gnu/packages/icu4c.scm
@@ -73,4 +73,5 @@ C/C++ part.")
     (source (origin
               (inherit (package-source icu4c))
               (patches
-               (search-patches "icu4c-reset-keyword-list-iterator.patch"))))))
+               (search-patches "icu4c-CVE-2017-7867-CVE-2017-7868.patch"
+                               "icu4c-reset-keyword-list-iterator.patch"))))))
diff --git a/gnu/packages/image-viewers.scm b/gnu/packages/image-viewers.scm
index 830ce10ea6..768ed325bd 100644
--- a/gnu/packages/image-viewers.scm
+++ b/gnu/packages/image-viewers.scm
@@ -6,6 +6,7 @@
 ;;; Copyright © 2017 Alex Griffin <a@ajgrf.com>
 ;;; Copyright © 2017 ng0 <contact.ng0@cryptolab.net>
 ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
+;;; Copyright © 2017 nee <nee-git@hidamari.blue>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -28,6 +29,7 @@
   #:use-module (guix packages)
   #:use-module (guix build-system gnu)
   #:use-module (guix build-system cmake)
+  #:use-module (guix build-system python)
   #:use-module (gnu packages autotools)
   #:use-module (gnu packages algebra)
   #:use-module (gnu packages base)
@@ -44,6 +46,7 @@
   #:use-module (gnu packages maths)
   #:use-module (gnu packages photo)
   #:use-module (gnu packages pkg-config)
+  #:use-module (gnu packages python)
   #:use-module (gnu packages qt)
   #:use-module (gnu packages xorg)
   #:use-module (gnu packages))
@@ -360,3 +363,42 @@ imaging.  It supports several HDR and LDR image formats, and it can:
 @item Copy EXIF data between sets of images.
 @end itemize\n")
     (license license:gpl2+)))
+
+;; CBR and RAR are currently unsupported, due to non-free dependencies.
+;; For optional PDF support, you can install the mupdf package.
+(define-public mcomix
+  (package
+    (name "mcomix")
+    (version "1.2.1")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://sourceforge/mcomix/MComix-" version
+                           "/mcomix-" version ".tar.bz2"))
+       (sha256
+        (base32
+         "0fzsf9pklhfs1rzwzj64c0v30b74nk94p93h371rpg45qnfiahvy"))))
+    (build-system python-build-system)
+    (inputs
+     `(("p7zip" ,p7zip)
+       ("python2-pillow" ,python2-pillow)
+       ("python2-pygtk" ,python2-pygtk)))
+    (arguments
+     ;; Python 2.5 or newer (Python 3 and up is not supported)
+     `(#:python ,python-2
+       #:phases
+       (modify-phases %standard-phases
+         (add-after 'unpack 'configure
+           (lambda* (#:key inputs #:allow-other-keys)
+             (let ((p7zip (assoc-ref inputs "p7zip")))
+               ;; insert absolute path to 7z executable
+               (substitute* "mcomix/archive/sevenzip_external.py"
+                 (("_7z_executable = -1")
+                  (string-append "_7z_executable = u'" p7zip "/bin/7z'"))))
+             #t)))))
+    (home-page "https://sourceforge.net/p/mcomix/wiki/Home/")
+    (synopsis "Image viewer for comics")
+    (description "MComix is a customizable image viewer that specializes as
+a comic and manga reader.  It supports a variety of container formats
+including CBZ, CB7, CBT, LHA.")
+    (license license:gpl2+)))
diff --git a/gnu/packages/image.scm b/gnu/packages/image.scm
index 2725c168b6..2027395ca6 100644
--- a/gnu/packages/image.scm
+++ b/gnu/packages/image.scm
@@ -598,7 +598,7 @@ compose, and analyze GIF images.")
 (define-public imlib2
   (package
     (name "imlib2")
-    (version "1.4.9")
+    (version "1.4.10")
     (source (origin
               (method url-fetch)
               (uri (string-append
@@ -606,7 +606,7 @@ compose, and analyze GIF images.")
                     "/imlib2-" version ".tar.bz2"))
               (sha256
                (base32
-                "08809xxk2555yj6glixzw9a0x3x8cx55imd89kj3r0h152bn8a3x"))))
+                "0wm2q2xlkbm71k7mw2jyzbxgzylrkcj5yh6nq58w5gybhp98qs9z"))))
     (build-system gnu-build-system)
     (native-inputs
      `(("pkgconfig" ,pkg-config)))
diff --git a/gnu/packages/irc.scm b/gnu/packages/irc.scm
index f4ff7fcbef..4c8c7809be 100644
--- a/gnu/packages/irc.scm
+++ b/gnu/packages/irc.scm
@@ -5,6 +5,7 @@
 ;;; Copyright © 2015, 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2016 ng0 <ng0@libertad.pw>
 ;;; Copyright © 2017 Marius Bakke <mbakke@fastmail.com>
+;;; Copyright © 2017 Tobias Geerinckx-Rice <me@tobias.gr>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -141,14 +142,14 @@ SILC and ICB protocols via plugins.")
 (define-public weechat
   (package
     (name "weechat")
-    (version "1.7")
+    (version "1.7.1")
     (source (origin
               (method url-fetch)
-              (uri (string-append "http://weechat.org/files/src/weechat-"
+              (uri (string-append "https://weechat.org/files/src/weechat-"
                                   version ".tar.xz"))
               (sha256
                (base32
-                "1crdwlxj5liik32svflfac0s87vm6p8xm208yndigzsbg8rli4sr"))
+                "0c0waxrxq2v0r7981y1ajh9k78jfl223smwrj4v9c5z27iwh8ziz"))
               (patches (search-patches "weechat-python.patch"))))
     (build-system gnu-build-system)
     (native-inputs `(("autoconf" ,autoconf)
@@ -190,12 +191,13 @@ SILC and ICB protocols via plugins.")
                         #t))))))
     (synopsis "Extensible chat client")
     (description "WeeChat (Wee Enhanced Environment for Chat) is an
-Internet Relay Chat client, which is designed to be light and fast.
-The client uses a curses frontend, and there are remote interfaces
-for Web, Qt, Android and Emacs.  In WeeChat everything can be done
-with a keyboard, though it also supports mouse.  It is customizable
-and extensible with plugins and scripts.")
-    (home-page "http://www.weechat.org/")
+@dfn{Internet Relay Chat} (IRC) client, which is designed to be light and fast.
+The client uses a curses frontend, and there are remote interfaces for Web,
+Qt, Android, and Emacs.
+
+Everything in WeeChat can be done with the keyboard, though it also supports
+using a mouse.  It is customizable and extensible with plugins and scripts.")
+    (home-page "https://www.weechat.org/")
     (license license:gpl3)))
 
 (define-public ircii
diff --git a/gnu/packages/linux.scm b/gnu/packages/linux.scm
index 548a8b0a98..e6ede675c0 100644
--- a/gnu/packages/linux.scm
+++ b/gnu/packages/linux.scm
@@ -353,8 +353,8 @@ It has been modified to remove all non-free binary blobs.")
 
 (define %intel-compatible-systems '("x86_64-linux" "i686-linux"))
 
-(define %linux-libre-version "4.10.10")
-(define %linux-libre-hash "1py6hzv39hbyafkvz69pmcidwxbd7psp9jzmnm4dg4jj7j92m6b7")
+(define %linux-libre-version "4.10.12")
+(define %linux-libre-hash "10k86blssyhhv2xvdqygyg3h43qppkffi09mg6ckxjsfv7crrf8j")
 
 (define-public linux-libre
   (make-linux-libre %linux-libre-version
@@ -363,14 +363,14 @@ It has been modified to remove all non-free binary blobs.")
                     #:configuration-file kernel-config))
 
 (define-public linux-libre-4.9
-  (make-linux-libre "4.9.22"
-                    "1dvsbqkw7wvg40nmzdyiyvb0i54j5w6d9dvsvv7z87d2id56lqm0"
+  (make-linux-libre "4.9.24"
+                    "0554b5899wvzf3w6wxxxsniriq3mw31h23kb2xp9g815yhnw6acd"
                     %intel-compatible-systems
                     #:configuration-file kernel-config))
 
 (define-public linux-libre-4.4
-  (make-linux-libre "4.4.61"
-                    "12555h3yxymxgfgq3g33sy78g7rj6l8dpqr29z98kr9ybs93q7vj"
+  (make-linux-libre "4.4.63"
+                    "1ipzjrrgjd1cdfpj1110zav3wkq60xxagc2hvb50yni8wrxfbf40"
                     %intel-compatible-systems
                     #:configuration-file kernel-config))
 
diff --git a/gnu/packages/mail.scm b/gnu/packages/mail.scm
index 983629f85d..fb4a042a96 100644
--- a/gnu/packages/mail.scm
+++ b/gnu/packages/mail.scm
@@ -15,7 +15,7 @@
 ;;; Copyright © 2016 Lukas Gradl <lgradl@openmailbox.org>
 ;;; Copyright © 2016 Alex Kost <alezost@gmail.com>
 ;;; Copyright © 2016 Troy Sankey <sankeytms@gmail.com>
-;;; Copyright © 2016, 2017 ng0 <contact.ng0@cryptolab.net>
+;;; Copyright © 2016, 2017 ng0 <ng0@no-reply.pragmatique.xyz>
 ;;; Copyright © 2016 Clément Lassieur <clement@lassieur.org>
 ;;; Copyright © 2016, 2017 Arun Isaac <arunisaac@systemreboot.net>
 ;;; Copyright © 2016 John Darrington <jmd@gnu.org>
@@ -23,6 +23,7 @@
 ;;; Copyright © 2017 Thomas Danckaert <post@thomasdanckaert.be>
 ;;; Copyright © 2017 Kyle Meyer <kyle@kyleam.com>
 ;;; Copyright © 2017 Tobias Geerinckx-Rice <me@tobias.gr>
+;;; Copyright © 2017 Rene Saavedra <rennes@openmailbox.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -58,6 +59,7 @@
   #:use-module (gnu packages emacs)
   #:use-module (gnu packages enchant)
   #:use-module (gnu packages ghostscript)
+  #:use-module (gnu packages gettext)
   #:use-module (gnu packages glib)
   #:use-module (gnu packages gnome)
   #:use-module (gnu packages gnupg)
@@ -94,6 +96,7 @@
   #:use-module (gnu packages tls)
   #:use-module (gnu packages networking)
   #:use-module (gnu packages web)
+  #:use-module (gnu packages webkit)
   #:use-module (gnu packages xml)
   #:use-module (gnu packages xorg)
   #:use-module (gnu packages docbook)
@@ -222,14 +225,14 @@ aliasing facilities to work just as they would on normal mail.")
 (define-public mutt
   (package
     (name "mutt")
-    (version "1.8.1")
+    (version "1.8.2")
     (source (origin
              (method url-fetch)
              (uri (string-append "https://bitbucket.org/mutt/mutt/downloads/"
                                  "mutt-" version ".tar.gz"))
              (sha256
               (base32
-               "1b8dggq5x1b77a9i9250b3jhv2iddfzhr9rix1yfzckdms65mr8b"))
+               "0dgjjryp1ggbc6ivy9cfz5jl3gnbahb6d6hcwn7c7wk5npqpn18x"))
              (patches (search-patches "mutt-store-references.patch"))))
     (build-system gnu-build-system)
     (inputs
@@ -262,16 +265,15 @@ operating systems.")
   (package
     (inherit mutt)
     (name "neomutt")
-    (version "20170306")
+    (version "20170421")
     (source
      (origin
        (method url-fetch)
        (uri (string-append "https://github.com/" name "/" name
                            "/archive/" name "-" version ".tar.gz"))
-       (file-name (string-append name "-" version ".tar.gz"))
        (sha256
         (base32
-         "0qwcbjm9j1hgzmybw15w53pvfbqcdf47d4sw21s6r2yaj8kx1hag"))))
+         "09f1abad0vdn08x80hadjccjpnzcbn5fjpj749gb819biyqkl0y2"))))
     (inputs
      `(("cyrus-sasl" ,cyrus-sasl)
        ("gdbm" ,gdbm)
@@ -290,6 +292,7 @@ operating systems.")
     (native-inputs
      `(("autoconf" ,autoconf)
        ("automake" ,automake)
+       ("gettext-minimal" ,gettext-minimal)
        ("pkg-config" ,pkg-config)))
     (arguments
      `(#:configure-flags
@@ -336,8 +339,7 @@ operating systems.")
     (synopsis "Command-line mail reader based on Mutt")
     (description
      "NeoMutt is a command-line mail reader which is based on mutt.
-It adds a large amount of features to mutt, and they all find their way
-into mutt, so it is not a fork but a large set of feature patches.")))
+It adds a large amount of new and improved features to mutt.")))
 
 (define-public gmime
   (package
@@ -2284,3 +2286,58 @@ tools and applications:
 @item pilot, the standalone file system navigator
 @end enumerate\n")
     (license asl2.0)))
+
+(define-public balsa
+  (package
+    (name "balsa")
+    (version "2.5.3")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "https://pawsa.fedorapeople.org/balsa/balsa-"
+                           version ".tar.bz2"))
+       (sha256
+        (base32
+         "15jkwp3ylbwd8iha4dr37z1xb6mkk31ym90vv3h2a5xk2rmym5mq"))))
+    (build-system gnu-build-system)
+    (arguments
+     `(#:configure-flags
+       '(;; Balsa tries to install additional MIME icons
+         ;; under gtk+ directory.
+         "--enable-extra-mimeicons=no"
+         "--with-gtksourceview"
+         "--with-canberra"
+         "--with-spell-checker=gtkspell"
+         "--with-gpgme"
+         "--with-sqlite"
+         "--with-compface"
+         "--with-ldap")))
+    (inputs
+     `(("cyrus-sasl" ,cyrus-sasl)
+       ("enchant" ,enchant)
+       ("gdk-pixbuf" ,gdk-pixbuf)
+       ("gmime" ,gmime)
+       ("gnutls" ,gnutls)
+       ("gpgme" ,gpgme)
+       ("gtk+" ,gtk+)
+       ("gtksourceview" ,gtksourceview)
+       ("gtkspell3" ,gtkspell3)
+       ("libcanberra" ,libcanberra)
+       ("libesmtp" ,libesmtp)
+       ("libnotify" ,libnotify)
+       ("openldap" ,openldap)
+       ("sqlite" ,sqlite)
+       ("webkitgtk" ,webkitgtk)))
+    (native-inputs
+     `(("compface" ,compface)
+       ("glib" ,glib "bin")
+       ("intltool" ,intltool)
+       ("pkg-config" ,pkg-config)
+       ("yelp-tools" ,yelp-tools)))
+    (home-page "https://pawsa.fedorapeople.org/balsa")
+    (synopsis "E-mail client for GNOME")
+    (description "Balsa is a highly configurable and robust mail client for
+the GNOME desktop.  It supports both POP3 and IMAP servers as well as the
+mbox, maildir and mh local mailbox formats.  Balsa also supports SMTP and/or
+the use of a local MTA such as Sendemail.")
+    (license gpl3+)))
diff --git a/gnu/packages/maths.scm b/gnu/packages/maths.scm
index 272a0979ad..0a11da9eaf 100644
--- a/gnu/packages/maths.scm
+++ b/gnu/packages/maths.scm
@@ -489,7 +489,7 @@ singular value problems.")
 (define-public gnuplot
   (package
     (name "gnuplot")
-    (version "5.0.5")
+    (version "5.0.6")
     (source (origin
               (method url-fetch)
               (uri (string-append "mirror://sourceforge/gnuplot/gnuplot/"
@@ -497,7 +497,7 @@ singular value problems.")
                                   version ".tar.gz"))
        (sha256
         (base32
-         "0lr065qdlgss8lmy31l7hkmnk9fp4lvqq9qgb1f1209f36zy1wr5"))))
+         "0q5lr6nala3ln6f3yp6g17ziymb9r9gx9zylnw1y3hjmwl9lggjv"))))
     (build-system gnu-build-system)
     (inputs `(("readline" ,readline)
               ("cairo" ,cairo)
diff --git a/gnu/packages/messaging.scm b/gnu/packages/messaging.scm
index cbb4d4eaba..59e2b23d32 100644
--- a/gnu/packages/messaging.scm
+++ b/gnu/packages/messaging.scm
@@ -434,24 +434,23 @@ simultaneously and therefore appear under the same nickname on IRC.")
 (define-public python-nbxmpp
   (package
     (name "python-nbxmpp")
-    (version "0.5.3")
+    (version "0.5.5")
     (source
      (origin
        (method url-fetch)
-       (uri (string-append "https://pypi.python.org/packages/source/n/nbxmpp/"
-                           "nbxmpp-" version ".tar.gz"))
+       (uri (pypi-uri "nbxmpp" version))
        (sha256
         (base32
-         "0dcr786dyips1fdvgsn8yvpgcz5j7217fi05c29cfypdl8jnp6mp"))))
+         "1gnzrzrdl4nii1sc5x8p5iw2ya5sl70j3nn34abqsny51p2pzmv6"))))
     (build-system python-build-system)
-    ;; No tests included
-    (arguments `(#:tests? #f))
-    (home-page "http://python-nbxmpp.gajim.org")
+    (arguments
+     `(#:tests? #f))                    ; no tests
+    (home-page "https://dev.gajim.org/gajim/python-nbxmpp")
     (synopsis "Non-blocking Jabber/XMPP module")
     (description
      "The goal of this python library is to provide a way for Python
 applications to use Jabber/XMPP networks in a non-blocking way.  This library
-was initially a fork of xmpppy, but is using non-blocking sockets.")
+was initially a fork of xmpppy, but uses non-blocking sockets.")
     (license license:gpl3+)))
 
 (define-public python2-nbxmpp
diff --git a/gnu/packages/moreutils.scm b/gnu/packages/moreutils.scm
index 965876b971..b343a8db6d 100644
--- a/gnu/packages/moreutils.scm
+++ b/gnu/packages/moreutils.scm
@@ -1,6 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2015 Taylan Ulrich Bayırlı/Kammer <taylanbayirli@gmail.com>
-;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2016, 2017 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2016 Tobias Geerinckx-Rice <me@tobias.gr>
 ;;;
 ;;; This file is part of GNU Guix.
@@ -30,21 +30,21 @@
 (define-public moreutils
   (package
     (name "moreutils")
-    (version "0.59")
+    (version "0.60")
     (source
      (origin
        (method url-fetch)
        (uri (list
              (string-append
               "mirror://debian/pool/main/m/moreutils/moreutils_"
-              version ".orig.tar.gz")
+              version ".orig.tar.xz")
              ;; The main Debian mirrors only hold the current packages.
              (string-append
-              "http://snapshot.debian.org/archive/debian/20161223T212806Z"
-              "/pool/main/m/moreutils/moreutils_0.59.orig.tar.gz")))
+              "http://snapshot.debian.org/archive/debian-debug/20170109T210531Z"
+              "/pool/main/m/moreutils/moreutils_0.60.orig.tar.xz")))
        (sha256
         (base32
-         "1d6ik3j4lwp90vb93p7yv60k6vk2chz448d1z9xrmxvv371i33m4"))))
+         "1i8pphg5i5y4x1s1hz73gqhispgspr13bysmk9vh7l6jrfx1hbg4"))))
     (build-system gnu-build-system)
     ;; For building the manual pages.
     (native-inputs
diff --git a/gnu/packages/networking.scm b/gnu/packages/networking.scm
index cb9903791e..efef2d5a7a 100644
--- a/gnu/packages/networking.scm
+++ b/gnu/packages/networking.scm
@@ -1,6 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2014, 2017 Ludovic Courtès <ludo@gnu.org>
-;;; Copyright © 2015, 2016 Ricardo Wurmus <rekado@elephly.net>
+;;; Copyright © 2015, 2016, 2017 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
 ;;; Copyright © 2015, 2016 Stefan Reichör <stefan@xsteve.at>
 ;;; Copyright © 2016 Raimon Grau <raimonster@gmail.com>
@@ -1122,6 +1122,24 @@ IPFIX, RSPAN, CLI, LACP, 802.1ag).")
            license:bsd-2 license:bsd-3
            license:asl2.0))))           ; all other
 
+(define-public python-ipy
+  (package
+    (name "python-ipy")
+    (version "0.83")
+    (source (origin
+              (method url-fetch)
+              (uri (pypi-uri "IPy" version))
+              (sha256
+               (base32
+                "1f6sdrxclifky4gvkf4gvyv5hx3fjh8vzspnfrqki6qm5d9mmnk1"))))
+    (build-system python-build-system)
+    (home-page "https://github.com/autocracy/python-ipy/")
+    (synopsis "Python class and tools for handling IP addresses and networks")
+    (description "The @code{IP} class allows a comfortable parsing and
+handling for most notations in use for IPv4 and IPv6 addresses and
+networks.")
+    (license license:bsd-3)))
+
 (define-public speedtest-cli
   (package
     (name "speedtest-cli")
diff --git a/gnu/packages/openldap.scm b/gnu/packages/openldap.scm
index 627319bda8..b67510647d 100644
--- a/gnu/packages/openldap.scm
+++ b/gnu/packages/openldap.scm
@@ -2,6 +2,7 @@
 ;;; Copyright © 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2013 Andreas Enge <andreas@enge.fr>
 ;;; Copyright © 2016 Leo Famulari <leo@famulari.name>
+;;; Copyright © 2017 Ricardo Wurmus <rekado@elephly.net>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -26,8 +27,10 @@
   #:use-module (gnu packages gnupg)
   #:use-module (gnu packages groff)
   #:use-module (gnu packages icu4c)
+  #:use-module (gnu packages linux)
+  #:use-module (gnu packages python)
   #:use-module (gnu packages tls)
-  #:use-module ((guix licenses) #:select (openldap2.8))
+  #:use-module ((guix licenses) #:select (openldap2.8 lgpl2.1+))
   #:use-module (guix packages)
   #:use-module (guix download)
   #:use-module (guix build-system gnu))
@@ -74,3 +77,35 @@
     "OpenLDAP is a free implementation of the Lightweight Directory Access Protocol.")
    (license openldap2.8)
    (home-page "http://www.openldap.org/")))
+
+(define-public nss-pam-ldapd
+  (package
+    (name "nss-pam-ldapd")
+    (version "0.9.7")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "https://arthurdejong.org/nss-pam-ldapd/"
+                                  "nss-pam-ldapd-" version ".tar.gz"))
+              (sha256
+               (base32
+                "1sw36w6zkzvabvjckqick032j5p5xi0qi3sgnh0znzxz31jqvf0d"))))
+    (build-system gnu-build-system)
+    (arguments
+     `(#:configure-flags
+       (list (string-append "--with-pam-seclib-dir="
+                            (assoc-ref %outputs "out") "/lib/security/")
+             (string-append "--with-ldap-conf-file="
+                            (assoc-ref %outputs "out") "/etc/nslcd.conf"))))
+    (inputs
+     `(("linux-pam" ,linux-pam)
+       ("openldap" ,openldap)
+       ("python" ,python-2)))
+    (home-page "https://arthurdejong.org/nss-pam-ldapd")
+    (synopsis "NSS and PAM modules for LDAP")
+    (description "nss-pam-ldapd provides a @dfn{Name Service Switch} (NSS)
+module that allows your LDAP server to provide user account, group, host name,
+alias, netgroup, and basically any other information that you would normally
+get from @file{/etc} flat files or NIS.  It also provides a @dfn{Pluggable
+Authentication Module} (PAM) to do identity and authentication management with
+an LDAP server.")
+    (license lgpl2.1+)))
diff --git a/gnu/packages/package-management.scm b/gnu/packages/package-management.scm
index d4f83d3510..a931a0e269 100644
--- a/gnu/packages/package-management.scm
+++ b/gnu/packages/package-management.scm
@@ -91,6 +91,12 @@
                                          (assoc-ref %build-inputs
                                                     "libgcrypt")))
        #:parallel-tests? #f           ;work around <http://bugs.gnu.org/21097>
+
+       #:modules ((guix build gnu-build-system)
+                  (guix build utils)
+                  (ice-9 popen)
+                  (ice-9 rdelim))
+
        #:phases (modify-phases %standard-phases
                   (add-before
                    'configure 'copy-bootstrap-guile
@@ -139,19 +145,24 @@
                       ;; correct value, so set it.
                       (setenv "SHELL" (which "sh"))
                       #t))
-                  (add-after
-                   'install 'wrap-program
+                  (add-after 'install 'wrap-program
                    (lambda* (#:key inputs outputs #:allow-other-keys)
                      ;; Make sure the 'guix' command finds GnuTLS and
                      ;; Guile-JSON automatically.
                      (let* ((out    (assoc-ref outputs "out"))
+                            (guile  (assoc-ref inputs "guile"))
                             (json   (assoc-ref inputs "guile-json"))
                             (ssh    (assoc-ref inputs "guile-ssh"))
                             (gnutls (assoc-ref inputs "gnutls"))
+                            (effective
+                             (read-line
+                              (open-pipe* OPEN_READ
+                                          (string-append guile "/bin/guile")
+                                          "-c" "(display (effective-version))")))
                             (path   (string-append
-                                     json "/share/guile/site/2.0:"
-                                     ssh "/share/guile/site/2.0:"
-                                     gnutls "/share/guile/site/2.0")))
+                                     json "/share/guile/site/" effective ":"
+                                     ssh "/share/guile/site/" effective ":"
+                                     gnutls "/share/guile/site/" effective)))
 
                        (wrap-program (string-append out "/bin/guix")
                          `("GUILE_LOAD_PATH" ":" prefix (,path))
@@ -224,9 +235,9 @@ the Nix package manager.")
   ;;
   ;; Note: use a very short commit id; with a longer one, the limit on
   ;; hash-bang lines would be exceeded while running the tests.
-  (let ((commit "aabece2ef8f87c35ceb3678f39fcfd244b15bb0f"))
+  (let ((commit "25a49294caf2386e65fc1b12a2508324be0b1cc2"))
     (package (inherit guix-0.12.0)
-      (version (string-append "0.12.0-7." (string-take commit 4)))
+      (version (string-append "0.12.0-9." (string-take commit 4)))
       (source (origin
                 (method git-fetch)
                 (uri (git-reference
@@ -236,7 +247,7 @@ the Nix package manager.")
                       (commit commit)))
                 (sha256
                  (base32
-                  "0n8rrwwax9g6i38vq4y2xwb30irkv4c53mqcm5hqv78rb33x8z1l"))
+                  "0p4rh0629j89v4ka5dsp70a1xrfhg7sxjjq54p68vw7x5dkann4a"))
                 (file-name (string-append "guix-" version "-checkout"))))
       (arguments
        (substitute-keyword-arguments (package-arguments guix-0.12.0)
diff --git a/gnu/packages/patches/ceph-disable-cpu-optimizations.patch b/gnu/packages/patches/ceph-disable-cpu-optimizations.patch
index 6d20fe3da4..56a1654f29 100644
--- a/gnu/packages/patches/ceph-disable-cpu-optimizations.patch
+++ b/gnu/packages/patches/ceph-disable-cpu-optimizations.patch
@@ -1,12 +1,13 @@
-Disable CPU optimizations not supported by the vast majority of
-x86_64 systems. Also don't add anything for i686.
+Disable CPU optimizations not supported by all x86_64 systems. Also
+don't add anything for i686.
 
 --- a/cmake/modules/SIMDExt.cmake	2017-03-23 22:22:58.254071694 +0100
 +++ b/cmake/modules/SIMDExt.cmake	2017-03-23 22:23:22.446848845 +0100
-@@ -6,10 +6,6 @@
+@@ -5,11 +5,6 @@
+ # HAVE_ARM_NEON
  # HAVE_INTEL_SSE
  # HAVE_INTEL_SSE2
- # HAVE_INTEL_SSE3
+-# HAVE_INTEL_SSE3
 -# HAVE_INTEL_SSSE3
 -# HAVE_INTEL_PCLMUL
 -# HAVE_INTEL_SSE4_1
@@ -14,7 +15,7 @@ x86_64 systems. Also don't add anything for i686.
  #
  # SIMD_COMPILE_FLAGS
  #
-@@ -56,7 +53,7 @@
+@@ -56,7 +51,7 @@
    if(HAVE_ARM_NEON)
      set(SIMD_COMPILE_FLAGS "${SIMD_COMPILE_FLAGS} -mfpu=neon")
    endif()
@@ -23,10 +24,14 @@ x86_64 systems. Also don't add anything for i686.
    set(HAVE_INTEL 1)
    CHECK_C_COMPILER_FLAG(-msse HAVE_INTEL_SSE)
    if(HAVE_INTEL_SSE)
-@@ -70,20 +67,4 @@
-   if(HAVE_INTEL_SSE3)
-     set(SIMD_COMPILE_FLAGS "${SIMD_COMPILE_FLAGS} -msse3")
+@@ -66,24 +61,4 @@
+   if(HAVE_INTEL_SSE2)
+     set(SIMD_COMPILE_FLAGS "${SIMD_COMPILE_FLAGS} -msse2")
    endif()
+-  CHECK_C_COMPILER_FLAG(-msse3 HAVE_INTEL_SSE3)
+-  if(HAVE_INTEL_SSE3)
+-    set(SIMD_COMPILE_FLAGS "${SIMD_COMPILE_FLAGS} -msse3")
+-  endif()
 -  CHECK_C_COMPILER_FLAG(-mssse3 HAVE_INTEL_SSSE3)
 -  if(HAVE_INTEL_SSSE3)
 -    set(SIMD_COMPILE_FLAGS "${SIMD_COMPILE_FLAGS} -mssse3")
diff --git a/gnu/packages/patches/fabric-tests.patch b/gnu/packages/patches/fabric-tests.patch
new file mode 100644
index 0000000000..4a0ca9f8f1
--- /dev/null
+++ b/gnu/packages/patches/fabric-tests.patch
@@ -0,0 +1,15 @@
+The `fab` excecutable doesn't exist during the test phase as it is created
+dynamically during installation. Refer to the equivalent Python module
+directly.
+
+--- a/tests/test_utils.py
++++ b/tests/test_utils.py
+@@ -93,7 +93,7 @@
+     # perform when they are allowed to bubble all the way to the top. So, we
+     # invoke a subprocess and look at its stderr instead.
+     with quiet():
+-        result = local("fab -f tests/support/aborts.py kaboom", capture=True)
++        result = local("python -m fabric -f tests/support/aborts.py kaboom", capture=True)
+     # When error in #1318 is present, this has an extra "It burns!" at end of
+     # stderr string.
+     eq_(result.stderr, "Fatal error: It burns!\n\nAborting.")
\ No newline at end of file
diff --git a/gnu/packages/patches/gcc-libiberty-printf-decl.patch b/gnu/packages/patches/gcc-libiberty-printf-decl.patch
deleted file mode 100644
index a612c9e00e..0000000000
--- a/gnu/packages/patches/gcc-libiberty-printf-decl.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-This patch makes the exeception specifier of libiberty's 'asprintf'
-and 'vasprintf' declarations match those of glibc to work around the
-problem described at <https://gcc.gnu.org/ml/gcc-help/2016-04/msg00039.html>.
-
-The problem in part stems from the fact that libiberty is configured
-without _GNU_SOURCE (thus, it sets HAVE_DECL_ASPRINTF to 0), whereas libcc1
-is configured and built with _GNU_SOURCE, hence the conflicting declarations.
-
---- gcc-5.3.0/include/libiberty.h	2016-04-23 22:45:46.262709079 +0200
-+++ gcc-5.3.0/include/libiberty.h	2016-04-23 22:45:37.110635439 +0200
-@@ -625,7 +625,7 @@ extern int pwait (int, int *, int);
- /* Like sprintf but provides a pointer to malloc'd storage, which must
-    be freed by the caller.  */
- 
--extern int asprintf (char **, const char *, ...) ATTRIBUTE_PRINTF_2;
-+extern int asprintf (char **, const char *, ...) __THROWNL ATTRIBUTE_PRINTF_2;
- #endif
- 
- /* Like asprintf but allocates memory without fail. This works like
-@@ -637,7 +637,7 @@ extern char *xasprintf (const char *, ..
- /* Like vsprintf but provides a pointer to malloc'd storage, which
-    must be freed by the caller.  */
- 
--extern int vasprintf (char **, const char *, va_list) ATTRIBUTE_PRINTF(2,0);
-+extern int vasprintf (char **, const char *, va_list) __THROWNL ATTRIBUTE_PRINTF(2,0);
- #endif
- 
- /* Like vasprintf but allocates memory without fail. This works like
diff --git a/gnu/packages/patches/graphite2-CVE-2017-5436.patch b/gnu/packages/patches/graphite2-CVE-2017-5436.patch
new file mode 100644
index 0000000000..d7383ec8de
--- /dev/null
+++ b/gnu/packages/patches/graphite2-CVE-2017-5436.patch
@@ -0,0 +1,25 @@
+From 1ce331d5548b98ed8b818532b2556d6f2c7a3b83 Mon Sep 17 00:00:00 2001
+From: Martin Hosken <martin_hosken@sil.org>
+Date: Thu, 9 Mar 2017 22:04:04 +0000
+Subject: [PATCH] Ensure features have enough space. Fix from Mozilla
+
+---
+ src/FeatureMap.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/FeatureMap.cpp b/src/FeatureMap.cpp
+index b8c8405..83bd5f6 100644
+--- a/src/FeatureMap.cpp
++++ b/src/FeatureMap.cpp
+@@ -275,7 +275,7 @@ bool FeatureRef::applyValToFeature(uint32 val, Features & pDest) const
+     else
+       if (pDest.m_pMap!=&m_pFace->theSill().theFeatureMap())
+         return false;       //incompatible
+-    pDest.reserve(m_index);
++    pDest.reserve(m_index+1);
+     pDest[m_index] &= ~m_mask;
+     pDest[m_index] |= (uint32(val) << m_bits);
+     return true;
+-- 
+2.12.2
+
diff --git a/gnu/packages/patches/graphite2-check-code-point-limit.patch b/gnu/packages/patches/graphite2-check-code-point-limit.patch
new file mode 100644
index 0000000000..a9b6caf53f
--- /dev/null
+++ b/gnu/packages/patches/graphite2-check-code-point-limit.patch
@@ -0,0 +1,50 @@
+From 348c11e4571b534efdbd58a575bbea979c880b2f Mon Sep 17 00:00:00 2001
+From: Tim Eves <tim_eves@sil.org>
+Date: Wed, 1 Mar 2017 14:23:46 +0700
+Subject: [PATCH] Fix decoding of USV greater than U+110000
+
+Add test cases too
+---
+ src/inc/UtfCodec.h        | 4 ++--
+ tests/utftest/utftest.cpp | 3 +++
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/src/inc/UtfCodec.h b/src/inc/UtfCodec.h
+index 3417bac..9dc760f 100644
+--- a/src/inc/UtfCodec.h
++++ b/src/inc/UtfCodec.h
+@@ -124,7 +124,7 @@ struct _utf_codec<8>
+ private:
+     static const int8 sz_lut[16];
+     static const byte mask_lut[5];
+-
++    static const uchar_t    limit = 0x110000;
+ 
+ public:
+     typedef uint8   codeunit_t;
+@@ -157,7 +157,7 @@ public:
+             case 0:     l = -1; return 0xFFFD;
+         }
+ 
+-        if (l != seq_sz || toolong)
++        if (l != seq_sz || toolong  || u >= limit)
+         {
+             l = -l;
+             return 0xFFFD;
+diff --git a/tests/utftest/utftest.cpp b/tests/utftest/utftest.cpp
+index 21cb188..a23553a 100644
+--- a/tests/utftest/utftest.cpp
++++ b/tests/utftest/utftest.cpp
+@@ -8,6 +8,9 @@ struct test8
+     unsigned char str[12];
+ };
+ struct test8 tests8[] = {
++    { 0,  0, {0xF4, 0x90, 0x80, 0x80, 0,    0,    0,    0,    0,    0,    0,    0} },   // bad(4) [U+110000]
++    { 0,  0, {0xC0, 0x80, 0,    0,    0,    0,    0,    0,    0,    0,    0,    0} },   // bad(4) [U+110000]
++    { 0,  0, {0xA0, 0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0} },   // bad(4) [U+110000]    
+     { 4, -1, {0x7F, 0xDF, 0xBF, 0xEF, 0xBF, 0xBF, 0xF4, 0x8F, 0xBF, 0xBF, 0,    0} },   // U+7F, U+7FF, U+FFFF, U+10FFF
+     { 2,  3, {0x7F, 0xDF, 0xBF, 0xF0, 0x8F, 0xBF, 0xBF, 0xF4, 0x8F, 0xBF, 0xBF, 0} },   // U+7F, U+7FF, long(U+FFFF), U+10FFF
+     { 1,  1, {0x7F, 0xE0, 0x9F, 0xBF, 0xEF, 0xBF, 0xBF, 0xF4, 0x8F, 0xBF, 0xBF, 0} },   // U+7F, long(U+7FF), U+FFFF, U+10FFF
+-- 
+2.12.2
+
diff --git a/gnu/packages/patches/graphite2-fix-32-bit-wrap-arounds.patch b/gnu/packages/patches/graphite2-fix-32-bit-wrap-arounds.patch
new file mode 100644
index 0000000000..57d4ce2c6e
--- /dev/null
+++ b/gnu/packages/patches/graphite2-fix-32-bit-wrap-arounds.patch
@@ -0,0 +1,93 @@
+This patch incorporates the following 6 consecutive commits from the upstream
+graphite2 repository:
+
+75b83cd..: Martin Hosken 2017-03-28 Fix 32-bit wrap arounds
+1f97e36..: Martin Hosken 2017-03-28 balance comparisons in decompressor
+9493785..: Martin Hosken 2017-03-29 Speculative rounding fix
+09af043..: Tim Eves      2017-03-31 Move a MINMATCH to rhs of a comparisio
+28cc60d..: Tim Eves      2017-03-31 Deal with similar wrap around in literal_len
+8afc7d0..: Martin Hosken 2017-04-03 Fix 32-bit rollover in decompressor, again
+
+This diff was generated by the following command:
+
+  git diff 1ce331d5548b98ed..8afc7d0081959866
+
+
+diff --git a/src/Decompressor.cpp b/src/Decompressor.cpp
+index 084570f..56d531f 100644
+--- a/src/Decompressor.cpp
++++ b/src/Decompressor.cpp
+@@ -51,7 +51,7 @@ bool read_sequence(u8 const * &src, u8 const * const end, u8 const * &literal, u
+     literal = src;
+     src += literal_len;
+     
+-    if (src > end - 2)
++    if (src > end - 2 || src < literal)
+         return false;
+     
+     match_dist  = *src++;
+@@ -85,7 +85,7 @@ int lz4::decompress(void const *in, size_t in_size, void *out, size_t out_size)
+         {
+             // Copy in literal. At this point the last full sequence must be at
+             // least MINMATCH + 5 from the end of the output buffer.
+-            if (dst + align(literal_len) > dst_end - (MINMATCH+5))
++            if (align(literal_len) > unsigned(dst_end - dst - (MINMATCH+5)) || dst_end - dst < MINMATCH + 5)
+                 return -1;
+             dst = overrun_copy(dst, literal, literal_len);
+         }
+@@ -94,7 +94,8 @@ int lz4::decompress(void const *in, size_t in_size, void *out, size_t out_size)
+         //  decoded output.
+         u8 const * const pcpy = dst - match_dist;
+         if (pcpy < static_cast<u8*>(out)
+-                  || dst + match_len + MINMATCH > dst_end - 5)
++                  || match_len > unsigned(dst_end - dst - (MINMATCH+5))
++                  || dst_end - dst < MINMATCH + 5)
+             return -1;
+         if (dst > pcpy+sizeof(unsigned long) 
+             && dst + align(match_len + MINMATCH) <= dst_end)
+@@ -103,8 +104,8 @@ int lz4::decompress(void const *in, size_t in_size, void *out, size_t out_size)
+             dst = safe_copy(dst, pcpy, match_len + MINMATCH);
+     }
+     
+-    if (literal + literal_len > src_end
+-              || dst + literal_len > dst_end)
++    if (literal_len > src_end - literal
++              || literal_len > dst_end - dst)
+         return -1;
+     dst = fast_copy(dst, literal, literal_len);
+     
+diff --git a/src/Pass.cpp b/src/Pass.cpp
+index a4bac2e..683143c 100644
+--- a/src/Pass.cpp
++++ b/src/Pass.cpp
+@@ -171,7 +171,7 @@ bool Pass::readPass(const byte * const pass_start, size_t pass_length, size_t su
+     const uint16 * const o_actions = reinterpret_cast<const uint16 *>(p);
+     be::skip<uint16>(p, m_numRules + 1);
+     const byte * const states = p;
+-    if (e.test(p + 2u*m_numTransition*m_numColumns >= pass_end, E_BADPASSLENGTH)) return face.error(e);
++    if (e.test(2u*m_numTransition*m_numColumns >= (unsigned)(pass_end - p), E_BADPASSLENGTH)) return face.error(e);
+     be::skip<int16>(p, m_numTransition*m_numColumns);
+     be::skip<uint8>(p);
+     if (e.test(p != pcCode, E_BADPASSCCODEPTR)) return face.error(e);
+@@ -192,7 +192,7 @@ bool Pass::readPass(const byte * const pass_start, size_t pass_length, size_t su
+         m_cPConstraint = vm::Machine::Code(true, pcCode, pcCode + pass_constraint_len, 
+                                   precontext[0], be::peek<uint16>(sort_keys), *m_silf, face, PASS_TYPE_UNKNOWN);
+         if (e.test(!m_cPConstraint, E_OUTOFMEM)
+-                || e.test(!m_cPConstraint, m_cPConstraint.status() + E_CODEFAILURE))
++                || e.test(m_cPConstraint.status() != Code::loaded, m_cPConstraint.status() + E_CODEFAILURE))
+             return face.error(e);
+         face.error_context(face.error_context() - 1);
+     }
+diff --git a/src/Silf.cpp b/src/Silf.cpp
+index 72a22cd..d661992 100644
+--- a/src/Silf.cpp
++++ b/src/Silf.cpp
+@@ -191,7 +191,7 @@ bool Silf::readGraphite(const byte * const silf_start, size_t lSilf, Face& face,
+ 
+     const size_t clen = readClassMap(p, passes_start - p, version, e);
+     m_passes = new Pass[m_numPasses];
+-    if (e || e.test(p + clen > passes_start, E_BADPASSESSTART)
++    if (e || e.test(clen > unsigned(passes_start - p), E_BADPASSESSTART)
+           || e.test(!m_passes, E_OUTOFMEM))
+     { releaseBuffers(); return face.error(e); }
+ 
diff --git a/gnu/packages/patches/graphite2-non-linear-classes-even-number.patch b/gnu/packages/patches/graphite2-non-linear-classes-even-number.patch
new file mode 100644
index 0000000000..2bb1c9f94e
--- /dev/null
+++ b/gnu/packages/patches/graphite2-non-linear-classes-even-number.patch
@@ -0,0 +1,26 @@
+From 0646e4ee471183994f78a759269f0505617711f3 Mon Sep 17 00:00:00 2001
+From: Martin Hosken <martin_hosken@sil.org>
+Date: Tue, 18 Apr 2017 13:17:14 +0100
+Subject: [PATCH] Ensure non linear classes have even number of elements
+
+---
+ src/Silf.cpp | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/Silf.cpp b/src/Silf.cpp
+index d661992..9f2f954 100644
+--- a/src/Silf.cpp
++++ b/src/Silf.cpp
+@@ -293,7 +293,8 @@ size_t Silf::readClassMap(const byte *p, size_t data_len, uint32 version, Error
+         if (e.test(*o + 4 > max_off, E_HIGHCLASSOFFSET)                        // LookupClass doesn't stretch over max_off
+          || e.test(lookup[0] == 0                                                   // A LookupClass with no looks is a suspicious thing ...
+                     || lookup[0] * 2 + *o + 4 > max_off                             // numIDs lookup pairs fits within (start of LookupClass' lookups array, max_off]
+-                    || lookup[3] + lookup[1] != lookup[0], E_BADCLASSLOOKUPINFO))   // rangeShift:   numIDs  - searchRange
++                    || lookup[3] + lookup[1] != lookup[0], E_BADCLASSLOOKUPINFO)    // rangeShift:   numIDs  - searchRange
++         || e.test(((o[1] - *o) & 1) != 0, ERROROFFSET))                         // glyphs are in pairs so difference must be even.
+             return ERROROFFSET;
+     }
+ 
+-- 
+2.12.2
+
diff --git a/gnu/packages/patches/grub-CVE-2015-8370.patch b/gnu/packages/patches/grub-CVE-2015-8370.patch
deleted file mode 100644
index 5701b54759..0000000000
--- a/gnu/packages/patches/grub-CVE-2015-8370.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 88c9657960a6c5d3673a25c266781e876c181add Mon Sep 17 00:00:00 2001
-From: Hector Marco-Gisbert <hecmargi@upv.es>
-Date: Fri, 13 Nov 2015 16:21:09 +0100
-Subject: [PATCH] Fix security issue when reading username and password
-
-  This patch fixes two integer underflows at:
-    * grub-core/lib/crypto.c
-    * grub-core/normal/auth.c
-
-Signed-off-by: Hector Marco-Gisbert <hecmargi@upv.es>
-Signed-off-by: Ismael Ripoll-Ripoll <iripoll@disca.upv.es>
----
- grub-core/lib/crypto.c  | 2 +-
- grub-core/normal/auth.c | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c
-index 010e550..524a3d8 100644
---- a/grub-core/lib/crypto.c
-+++ b/grub-core/lib/crypto.c
-@@ -468,7 +468,7 @@ grub_password_get (char buf[], unsigned buf_size)
- 	  break;
- 	}
- 
--      if (key == '\b')
-+      if (key == '\b' && cur_len)
- 	{
- 	  cur_len--;
- 	  continue;
-diff --git a/grub-core/normal/auth.c b/grub-core/normal/auth.c
-index c6bd96e..5782ec5 100644
---- a/grub-core/normal/auth.c
-+++ b/grub-core/normal/auth.c
-@@ -172,7 +172,7 @@ grub_username_get (char buf[], unsigned buf_size)
- 	  break;
- 	}
- 
--      if (key == '\b')
-+      if (key == '\b' && cur_len)
- 	{
- 	  cur_len--;
- 	  grub_printf ("\b");
--- 
-1.9.1
-
diff --git a/gnu/packages/patches/grub-freetype.patch b/gnu/packages/patches/grub-freetype.patch
deleted file mode 100644
index 286830ccf8..0000000000
--- a/gnu/packages/patches/grub-freetype.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-commit fd0df6d098b1e6a4f60275c48a3ec88d15ba1fbb
-Author: Colin Watson <cjwatson@ubuntu.com>
-Date:   Fri Nov 29 12:19:36 2013 +0000
-
-    Fix build with FreeType 2.5.1
-    
-    * util/grub-gen-asciih.c: Include FT_SYNTHESIS_H rather than
-    <freetype/ftsynth.h>, fixing build with FreeType 2.5.1.
-    * util/grub-gen-widthspec.c: Likewise.
-    * util/grub-mkfont.c: Likewise.
-
-diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c
-index 0d8eb78..242dd01 100644
---- a/util/grub-mkfont.c
-+++ b/util/grub-mkfont.c
-@@ -43,7 +43,7 @@
- #include FT_FREETYPE_H
- #include FT_TRUETYPE_TAGS_H
- #include FT_TRUETYPE_TABLES_H
--#include <freetype/ftsynth.h>
-+#include FT_SYNTHESIS_H
- 
- #undef __FTERRORS_H__
- #define FT_ERROR_START_LIST   const char *ft_errmsgs[] = { 
diff --git a/gnu/packages/patches/grub-gets-undeclared.patch b/gnu/packages/patches/grub-gets-undeclared.patch
deleted file mode 100644
index 41dddbd9d0..0000000000
--- a/gnu/packages/patches/grub-gets-undeclared.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-This patch is needed to allow builds with newer versions of
-the GNU libc (2.16+).
-
-
-commit 66712c23388e93e5c518ebc8515140fa0c807348
-Author: Eric Blake <eblake@redhat.com>
-Date:   Thu Mar 29 13:30:41 2012 -0600
-
-    stdio: don't assume gets any more
-    
-    Gnulib intentionally does not have a gets module, and now that C11
-    and glibc have dropped it, we should be more proactive about warning
-    any user on a platform that still has a declaration of this dangerous
-    interface.
-    
-    * m4/stdio_h.m4 (gl_STDIO_H, gl_STDIO_H_DEFAULTS): Drop gets
-    support.
-    * modules/stdio (Makefile.am): Likewise.
-    * lib/stdio-read.c (gets): Likewise.
-    * tests/test-stdio-c++.cc: Likewise.
-    * m4/warn-on-use.m4 (gl_WARN_ON_USE_PREPARE): Fix comment.
-    * lib/stdio.in.h (gets): Make warning occur in more places.
-    * doc/posix-functions/gets.texi (gets): Update documentation.
-    Reported by Christer Solskogen.
-    
-    Signed-off-by: Eric Blake <eblake@redhat.com>
-
---- grub-2.00/grub-core/gnulib/stdio.in.h	2013-02-10 16:17:09.000000000 +0100
-+++ grub-2.00/grub-core/gnulib/stdio.in.h	2013-02-10 16:17:11.000000000 +0100
-@@ -137,12 +137,6 @@ _GL_WARN_ON_USE (fflush, "fflush is not
-                  "use gnulib module fflush for portable POSIX compliance");
- #endif
- 
--/* It is very rare that the developer ever has full control of stdin,
--   so any use of gets warrants an unconditional warning.  Assume it is
--   always declared, since it is required by C89.  */
--#undef gets
--_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
--
- #if @GNULIB_FOPEN@
- # if @REPLACE_FOPEN@
- #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
diff --git a/gnu/packages/patches/guile-arm-fixes.patch b/gnu/packages/patches/guile-arm-fixes.patch
deleted file mode 100644
index 62bcf0fa7b..0000000000
--- a/gnu/packages/patches/guile-arm-fixes.patch
+++ /dev/null
@@ -1,203 +0,0 @@
-Apply fixes for ARM to Guile.
-
-From df8c52e93dfa3965e4714275f4b8cea2c8e0170b Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= <ludo@gnu.org>
-Date: Fri, 4 Jul 2014 15:35:06 +0200
-Subject: [PATCH] Recognize arm-* target triplets.
-
-Reported by Sylvain Beucler <beuc@beuc.net>.
-
-* module/system/base/target.scm (cpu-endianness): Add case where CPU is
-  "arm".
-* test-suite/tests/asm-to-bytecode.test ("cross-compilation")["arm-unknown-linux-androideabi"]:
-  New test.
----
- module/system/base/target.scm         | 4 +++-
- test-suite/tests/asm-to-bytecode.test | 5 ++++-
- 2 files changed, 7 insertions(+), 2 deletions(-)
-
-diff --git a/module/system/base/target.scm b/module/system/base/target.scm
-index c74ae67..cefa951 100644
---- a/module/system/base/target.scm
-+++ b/module/system/base/target.scm
-@@ -1,6 +1,6 @@
- ;;; Compilation targets
- 
--;; Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc.
-+;; Copyright (C) 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
- 
- ;; This library is free software; you can redistribute it and/or
- ;; modify it under the terms of the GNU Lesser General Public
-@@ -72,6 +72,8 @@
-              (endianness big))
-             ((string-match "^arm.*el" cpu)
-              (endianness little))
-+            ((string=? "arm" cpu)                ;ARMs are LE by default
-+             (endianness little))
-             (else
-              (error "unknown CPU endianness" cpu)))))
- 
-diff --git a/test-suite/tests/asm-to-bytecode.test b/test-suite/tests/asm-to-bytecode.test
-index 6d2f20e..62ea0ed 100644
---- a/test-suite/tests/asm-to-bytecode.test
-+++ b/test-suite/tests/asm-to-bytecode.test
-@@ -1,6 +1,6 @@
- ;;;; Assembly to bytecode compilation -*- mode: scheme; coding: utf-8; -*-
- ;;;;
--;;;; 	Copyright (C) 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
-+;;;; 	Copyright (C) 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
- ;;;;
- ;;;; This library is free software; you can redistribute it and/or
- ;;;; modify it under the terms of the GNU Lesser General Public
-@@ -205,6 +205,9 @@
-   (test-target "x86_64-unknown-linux-gnux32"      ; x32 ABI (Debian tuplet)
-                (endianness little) 4)
- 
-+  (test-target "arm-unknown-linux-androideabi"
-+               (endianness little) 4)
-+
-   (pass-if-exception "unknown target"
-     exception:miscellaneous-error
-     (call-with-values (lambda ()
--- 
-2.1.2
-
-From ffd3e55cfd12a3559621e3130d613d319243512d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= <ludo@gnu.org>
-Date: Fri, 4 Jul 2014 17:26:41 +0200
-Subject: [PATCH] Recognize more ARM targets.
-
-Suggested by Dale P. Smith.
-
-* module/system/base/target.scm (cpu-endianness): Add cases for
-  "arm.*eb", "^aarch64.*be", and "aarch64".  Change "arm" case to
-  "arm.*".
-  (triplet-pointer-size): Allow underscore as in 'aarch64_be'.
-* test-suite/tests/asm-to-bytecode.test ("cross-compilation")["armeb-unknown-linux-gnu",
-  "aarch64-linux-gnu", "aarch64_be-linux-gnu"]: New tests.
----
- module/system/base/target.scm         | 10 ++++++++--
- test-suite/tests/asm-to-bytecode.test |  6 ++++++
- 2 files changed, 14 insertions(+), 2 deletions(-)
-
-diff --git a/module/system/base/target.scm b/module/system/base/target.scm
-index cefa951..31e3fea 100644
---- a/module/system/base/target.scm
-+++ b/module/system/base/target.scm
-@@ -72,7 +72,13 @@
-              (endianness big))
-             ((string-match "^arm.*el" cpu)
-              (endianness little))
--            ((string=? "arm" cpu)                ;ARMs are LE by default
-+            ((string-match "^arm.*eb" cpu)
-+             (endianness big))
-+            ((string-prefix? "arm" cpu)          ;ARMs are LE by default
-+             (endianness little))
-+            ((string-match "^aarch64.*be" cpu)
-+             (endianness big))
-+            ((string=? "aarch64" cpu)
-              (endianness little))
-             (else
-              (error "unknown CPU endianness" cpu)))))
-@@ -97,7 +103,7 @@
-           ((string-match "^x86_64-.*-gnux32" triplet) 4)  ; x32
- 
-           ((string-match "64$" cpu) 8)
--          ((string-match "64[lbe][lbe]$" cpu) 8)
-+          ((string-match "64_?[lbe][lbe]$" cpu) 8)
-           ((member cpu '("sparc" "powerpc" "mips" "mipsel")) 4)
-           ((string-match "^arm.*" cpu) 4)
-           (else (error "unknown CPU word size" cpu)))))
-diff --git a/test-suite/tests/asm-to-bytecode.test b/test-suite/tests/asm-to-bytecode.test
-index 62ea0ed..8aeba84 100644
---- a/test-suite/tests/asm-to-bytecode.test
-+++ b/test-suite/tests/asm-to-bytecode.test
-@@ -207,6 +207,12 @@
- 
-   (test-target "arm-unknown-linux-androideabi"
-                (endianness little) 4)
-+  (test-target "armeb-unknown-linux-gnu"
-+               (endianness big) 4)
-+  (test-target "aarch64-linux-gnu"
-+               (endianness little) 8)
-+  (test-target "aarch64_be-linux-gnu"
-+               (endianness big) 8)
- 
-   (pass-if-exception "unknown target"
-     exception:miscellaneous-error
--- 
-2.1.2
-
-From a85c78ea1393985fdb6e6678dea19135c553d341 Mon Sep 17 00:00:00 2001
-From: Mark H Weaver <mhw@netris.org>
-Date: Fri, 19 Sep 2014 21:18:09 -0400
-Subject: [PATCH] VM: ASM_MUL for ARM: Add earlyclobber constraint to the SMULL
- outputs.
-
-Reported by Rob Browning <rlb@defaultvalue.org>.
-
-* libguile/vm-i-scheme.c (ASM_MUL)[ARM]: Add earlyclobber (&) constraint
-  to the SMULL output registers.
----
- libguile/vm-i-scheme.c | 5 ++---
- 1 file changed, 2 insertions(+), 3 deletions(-)
-
-diff --git a/libguile/vm-i-scheme.c b/libguile/vm-i-scheme.c
-index 587aa95..162efab 100644
---- a/libguile/vm-i-scheme.c
-+++ b/libguile/vm-i-scheme.c
-@@ -1,5 +1,4 @@
--/* Copyright (C) 2001, 2009, 2010, 2011, 2012, 2013,
-- *   2014 Free Software Foundation, Inc.
-+/* Copyright (C) 2001, 2009-2014 Free Software Foundation, Inc.
-  * 
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Lesser General Public License
-@@ -363,7 +362,7 @@ VM_DEFINE_FUNCTION (149, ge, "ge?", 2)
-       {									\
- 	scm_t_signed_bits rlo, rhi;					\
- 	asm ("smull %0, %1, %2, %3\n"					\
--	     : "=r" (rlo), "=r" (rhi)					\
-+	     : "=&r" (rlo), "=&r" (rhi)					\
- 	     : "r" (SCM_UNPACK (x) - scm_tc2_int),			\
- 	       "r" (SCM_I_INUM (y)));					\
- 	if (SCM_LIKELY (SCM_SRS (rlo, 31) == rhi))			\
--- 
-2.1.2
-
-From bed025bd2569b1c033f24d7d9e660e39ebf65cac Mon Sep 17 00:00:00 2001
-From: Mark H Weaver <mhw@netris.org>
-Date: Sat, 20 Sep 2014 03:59:51 -0400
-Subject: [PATCH] VM: Allow the C compiler to choose FP_REG on ARM.
-
-Reported by Rob Browning <rlb@defaultvalue.org>.
-
-* libguile/vm-engine.h (IP_REG)[__arm__]: Remove explicit register
-  choice ("r7") for FP_REG, which was reported to cause compilation
-  failures on ARM.
----
- libguile/vm-engine.h | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/libguile/vm-engine.h b/libguile/vm-engine.h
-index 46d4cff..e618be7 100644
---- a/libguile/vm-engine.h
-+++ b/libguile/vm-engine.h
-@@ -1,4 +1,4 @@
--/* Copyright (C) 2001, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
-+/* Copyright (C) 2001, 2009-2012, 2014 Free Software Foundation, Inc.
-  * 
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Lesser General Public License
-@@ -81,7 +81,7 @@
- #ifdef __arm__
- #define IP_REG asm("r9")
- #define SP_REG asm("r8")
--#define FP_REG asm("r7")
-+#define FP_REG
- #endif
- #endif
- 
--- 
-2.1.2
-
diff --git a/gnu/packages/patches/hurd-fix-eth-multiplexer-dependency.patch b/gnu/packages/patches/hurd-fix-eth-multiplexer-dependency.patch
new file mode 100644
index 0000000000..5f0da3eab3
--- /dev/null
+++ b/gnu/packages/patches/hurd-fix-eth-multiplexer-dependency.patch
@@ -0,0 +1,26 @@
+From ef0399bad41e60cb30d5073129abeb206076394a Mon Sep 17 00:00:00 2001
+From: Manolis Ragkousis <manolis837@gmail.com>
+Date: Sat, 8 Apr 2017 16:44:52 +0300
+Subject: [PATCH] eth-multiplexer: Fix iohelp missing dependency.
+
+* eth-multiplexer/Makefile (HURDLIBS): Add iohelp.
+---
+ eth-multiplexer/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/eth-multiplexer/Makefile b/eth-multiplexer/Makefile
+index 07f909e7..cefa0abd 100644
+--- a/eth-multiplexer/Makefile
++++ b/eth-multiplexer/Makefile
+@@ -26,7 +26,7 @@ MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h
+ device-MIGSFLAGS="-DMACH_PAYLOAD_TO_PORT=ports_payload_get_name"
+ OBJS = $(SRCS:.c=.o) $(MIGSTUBS)
+ LCLHDRS = ethernet.h util.h vdev.h netfs_impl.h
+-HURDLIBS = ports ihash fshelp shouldbeinlibc netfs bpf
++HURDLIBS = ports ihash iohelp fshelp shouldbeinlibc netfs bpf
+ LDLIBS = -lpthread
+ 
+ CFLAGS += -I$(top_srcdir)/libbpf
+-- 
+2.12.2
+
diff --git a/gnu/packages/patches/hypre-doc-tables.patch b/gnu/packages/patches/hypre-doc-tables.patch
deleted file mode 100644
index 6a852ee78e..0000000000
--- a/gnu/packages/patches/hypre-doc-tables.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-Fixes doc++'s treatment of tabular within a parameter block.
-
-From commit 883925f8a at http://github.com/LLNL/hypre
-
---- hypre-2.10.1/src/parcsr_ls/HYPRE_parcsr_ls.h	2015-12-04 22:12:19.000000000 -0600
-+++ hypre-2.10.1/src/parcsr_ls/HYPRE_parcsr_ls.h	2016-03-16 09:02:58.547501336 -0500
-@@ -1154,8 +1154,6 @@
-  * Set the symmetry parameter for the
-  * ParaSails preconditioner.
-  *
-- * @param solver [IN] Preconditioner object for which to set symmetry parameter.
-- * @param sym [IN] Value of the symmetry parameter:
-  * \begin{tabular}{|c|l|} \hline 
-  * value & meaning \\ \hline 
-  * 0 & nonsymmetric and/or indefinite problem, and nonsymmetric preconditioner\\
-@@ -1163,6 +1161,9 @@
-  * 2 & nonsymmetric, definite problem, and SPD (factored) preconditioner \\
-  * \hline
-  * \end{tabular}
-+ * 
-+ * @param solver [IN] Preconditioner object for which to set symmetry parameter.
-+ * @param sym [IN] Value of the symmetry parameter:
-  **/
- HYPRE_Int HYPRE_ParaSailsSetSym(HYPRE_Solver solver,
-                                 HYPRE_Int    sym);
diff --git a/gnu/packages/patches/hypre-ldflags.patch b/gnu/packages/patches/hypre-ldflags.patch
deleted file mode 100644
index a94fafa463..0000000000
--- a/gnu/packages/patches/hypre-ldflags.patch
+++ /dev/null
@@ -1,9 +0,0 @@
---- hypre-2.10.1/src/lib/Makefile.orig	2016-03-11 16:04:03.740259228 -0600
-+++ hypre-2.10.1/src/lib/Makefile	2016-03-11 16:04:57.296260190 -0600
-@@ -107,5 +107,5 @@
- 
- libHYPRE.so: ${FILES_HYPRE}
- 	@echo  "Building $@ ... "
--	${BUILD_CC_SHARED} -o ${SONAME} ${FILES_HYPRE} ${SOLIBS} ${SHARED_SET_SONAME}${SONAME} ${SHARED_OPTIONS}
-+	${BUILD_CC_SHARED} ${LDFLAGS} -o ${SONAME} ${FILES_HYPRE} ${SOLIBS} ${SHARED_SET_SONAME}${SONAME} ${SHARED_OPTIONS}
- 	ln -s ${SONAME} $@
diff --git a/gnu/packages/patches/icecat-avoid-bundled-libraries.patch b/gnu/packages/patches/icecat-avoid-bundled-libraries.patch
index 267f7b8aac..114631517a 100644
--- a/gnu/packages/patches/icecat-avoid-bundled-libraries.patch
+++ b/gnu/packages/patches/icecat-avoid-bundled-libraries.patch
@@ -1,8 +1,8 @@
 Fixes needed when avoiding bundled libraries.
 
---- icecat-45.3.0/xpcom/build/moz.build.orig
-+++ icecat-45.3.0/xpcom/build/moz.build
-@@ -92,10 +92,5 @@
+--- icecat-52.0.2/xpcom/build/moz.build.orig
++++ icecat-52.0.2/xpcom/build/moz.build
+@@ -93,10 +93,5 @@
      '/docshell/base',
  ]
  
@@ -13,38 +13,23 @@ Fixes needed when avoiding bundled libraries.
 -
  if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
      CXXFLAGS += CONFIG['TK_CFLAGS']
---- icecat-45.3.0/storage/moz.build.orig
-+++ icecat-45.3.0/storage/moz.build
-@@ -108,7 +108,6 @@
- DEFINES['SQLITE_MAX_LIKE_PATTERN_LENGTH'] = 50000
+--- icecat-52.0.2/storage/moz.build.orig
++++ icecat-52.0.2/storage/moz.build
+@@ -114,7 +114,6 @@
+     DEFINES['MOZ_MEMORY_TEMP_STORE_PRAGMA'] = True
  
  LOCAL_INCLUDES += [
 -    '/db/sqlite3/src',
      '/dom/base',
  ]
  
---- icecat-45.3.0/dom/indexedDB/moz.build.orig
-+++ icecat-45.3.0/dom/indexedDB/moz.build
-@@ -96,7 +96,6 @@
-     SOURCES['Key.cpp'].flags += ['-Wno-error=type-limits']
+--- icecat-52.0.2/dom/indexedDB/moz.build.orig
++++ icecat-52.0.2/dom/indexedDB/moz.build
+@@ -101,7 +101,6 @@
+     CXXFLAGS += ['-Wno-error=shadow']
  
  LOCAL_INCLUDES += [
 -    '/db/sqlite3/src',
      '/dom/base',
      '/dom/storage',
      '/dom/workers',
---- icecat-45.3.0/modules/libmar/tests/Makefile.in.orig
-+++ icecat-45.3.0/modules/libmar/tests/Makefile.in
-@@ -10,12 +10,5 @@
- ifndef MOZ_PROFILE_GENERATE
- libs::
- 	$(INSTALL) ../tool/signmar$(BIN_SUFFIX) $(TESTROOT)/unit
--	$(INSTALL) $(DEPTH)/dist/bin/$(DLL_PREFIX)nss3$(DLL_SUFFIX) $(TESTROOT)/unit
--ifndef MOZ_FOLD_LIBS
--	$(INSTALL) $(DEPTH)/dist/bin/$(DLL_PREFIX)nssutil3$(DLL_SUFFIX) $(TESTROOT)/unit
--	$(INSTALL) $(DEPTH)/dist/bin/$(DLL_PREFIX)plc4$(DLL_SUFFIX) $(TESTROOT)/unit
--	$(INSTALL) $(DEPTH)/dist/bin/$(DLL_PREFIX)nspr4$(DLL_SUFFIX) $(TESTROOT)/unit
--	$(INSTALL) $(DEPTH)/dist/bin/$(DLL_PREFIX)plds4$(DLL_SUFFIX) $(TESTROOT)/unit
--endif
- endif
- endif # Not Android
diff --git a/gnu/packages/patches/icecat-binutils.patch b/gnu/packages/patches/icecat-binutils.patch
deleted file mode 100644
index 53a3ed9bb0..0000000000
--- a/gnu/packages/patches/icecat-binutils.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-
-# HG changeset patch
-# User J. Brown <jb999@gmx.de>
-# Date 1476951900 14400
-# Node ID cca249d09ef600650e6127c18be438a37e9d4587
-# Parent  d8bbf1a3957fd25ff24bfee51331c150b154cc39
-Bug 1242901 - Fix linking libxul.so with binutils/GNU ld >= 2.26. r=glandium
-
-The build fails with:
-
-    /usr/bin/ld: ../../xpcom/components/nsComponentManager.o: relocation R_386_GOTOFF against protected data `start_kPStaticModules_NSModule' can not be used when making a shared object
-    /usr/bin/ld: final link failed: Bad value
-    collect2: error: ld returned 1 exit status
-
-This is a patch from 2016/04/27 16:36:50 ryoon found on
-http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/www/firefox45/patches/#dirlist.
-
-diff --git a/xpcom/components/Module.h b/xpcom/components/Module.h
---- a/xpcom/components/Module.h
-+++ b/xpcom/components/Module.h
-@@ -133,17 +133,17 @@ struct Module
- #if defined(MOZILLA_INTERNAL_API)
- #  define NSMODULE_NAME(_name) _name##_NSModule
- #  if defined(_MSC_VER)
- #    pragma section(".kPStaticModules$M", read)
- #    pragma comment(linker, "/merge:.kPStaticModules=.rdata")
- #    define NSMODULE_SECTION __declspec(allocate(".kPStaticModules$M"), dllexport)
- #  elif defined(__GNUC__)
- #    if defined(__ELF__)
--#      define NSMODULE_SECTION __attribute__((section(".kPStaticModules"), visibility("protected")))
-+#      define NSMODULE_SECTION __attribute__((section(".kPStaticModules"), visibility("default")))
- #    elif defined(__MACH__)
- #      define NSMODULE_SECTION __attribute__((section("__DATA, .kPStaticModules"), visibility("default")))
- #    elif defined (_WIN32)
- #      define NSMODULE_SECTION __attribute__((section(".kPStaticModules"), dllexport))
- #    endif
- #  endif
- #  if !defined(NSMODULE_SECTION)
- #    error Do not know how to define sections.
-
diff --git a/gnu/packages/patches/icecat-bug-1299500-pt10.patch b/gnu/packages/patches/icecat-bug-1299500-pt10.patch
new file mode 100644
index 0000000000..406738b8a5
--- /dev/null
+++ b/gnu/packages/patches/icecat-bug-1299500-pt10.patch
@@ -0,0 +1,1639 @@
+Based on the following HG changeset, but adapted to GNU IceCat and
+also assumes that the dom/devicestorage subtree is deleted by our
+snippet.  Note that the other parts of this patchset are downloaded
+directly from the upstream mozilla-esr52 mercurial repository.
+
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1489000545 -3600
+# Node ID 08f2bc167ae82a6f86e427283d8b972ba794b846
+# Parent  d63f3b14e5718b62c0adad2eab81b785250f3d4a
+Bug 1299500 - Get rid of DeviceStorage API - part 10 - DeviceStorage, r=ehsan, r=billm, a=jcristau
+
+diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf
+--- a/dom/bindings/Bindings.conf
++++ b/dom/bindings/Bindings.conf
+@@ -228,21 +228,16 @@ DOMInterfaces = {
+ 'DeviceAcceleration': {
+     'headerFile': 'mozilla/dom/DeviceMotionEvent.h',
+ },
+ 
+ 'DeviceRotationRate': {
+     'headerFile': 'mozilla/dom/DeviceMotionEvent.h',
+ },
+ 
+-'DeviceStorage': {
+-    'nativeType': 'nsDOMDeviceStorage',
+-    'headerFile': 'DeviceStorage.h',
+-},
+-
+ 'Document': {
+     'nativeType': 'nsIDocument',
+     'binaryNames': {
+         'documentURI': 'documentURIFromJS',
+         'URL': 'documentURIFromJS'
+     }
+ },
+ 
+diff --git a/dom/filesystem/DeviceStorageFileSystem.cpp b/dom/filesystem/DeviceStorageFileSystem.cpp
+--- a/dom/filesystem/DeviceStorageFileSystem.cpp
++++ b/dom/filesystem/DeviceStorageFileSystem.cpp
+@@ -1,26 +1,24 @@
+ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+ /* vim: set ts=8 sts=2 et sw=2 tw=80: */
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+  * You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ #include "mozilla/dom/DeviceStorageFileSystem.h"
+ 
+-#include "DeviceStorage.h"
+ #include "mozilla/Preferences.h"
+ #include "mozilla/dom/Directory.h"
+ #include "mozilla/dom/File.h"
+ #include "mozilla/dom/FileSystemUtils.h"
+ #include "mozilla/ipc/BackgroundParent.h"
+ #include "mozilla/Unused.h"
+ #include "nsCOMPtr.h"
+ #include "nsDebug.h"
+-#include "nsDeviceStorage.h"
+ #include "nsIFile.h"
+ #include "nsPIDOMWindow.h"
+ #include "nsGlobalWindow.h"
+ 
+ using namespace mozilla::ipc;
+ 
+ namespace mozilla {
+ namespace dom {
+@@ -37,44 +35,16 @@ DeviceStorageFileSystem::DeviceStorageFi
+     if (mozilla::Preferences::GetBool("device.storage.prompt.testing", false)) {
+       mPermissionCheckType = ePermissionCheckNotRequired;
+     } else {
+       mPermissionCheckType = ePermissionCheckRequired;
+     }
+   } else {
+     AssertIsOnBackgroundThread();
+   }
+-
+-  // Get the permission name required to access the file system.
+-  DebugOnly<nsresult> rv =
+-    DeviceStorageTypeChecker::GetPermissionForType(mStorageType, mPermission);
+-  NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "GetPermissionForType failed");
+-
+-  // Get the local path of the file system root.
+-  nsCOMPtr<nsIFile> rootFile;
+-  DeviceStorageFile::GetRootDirectoryForType(aStorageType,
+-                                             aStorageName,
+-                                             getter_AddRefs(rootFile));
+-
+-  Unused <<
+-    NS_WARN_IF(!rootFile ||
+-               NS_FAILED(rootFile->GetPath(mLocalOrDeviceStorageRootPath)));
+-
+-  if (!XRE_IsParentProcess()) {
+-    return;
+-  }
+-
+-  // DeviceStorageTypeChecker is a singleton object and must be initialized on
+-  // the main thread. We initialize it here so that we can use it on the worker
+-  // thread.
+-  if (NS_IsMainThread()) {
+-    DebugOnly<DeviceStorageTypeChecker*> typeChecker =
+-      DeviceStorageTypeChecker::CreateOrGet();
+-    MOZ_ASSERT(typeChecker);
+-  }
+ }
+ 
+ DeviceStorageFileSystem::~DeviceStorageFileSystem()
+ {
+   AssertIsOnOwningThread();
+ }
+ 
+ already_AddRefed<FileSystemBase>
+diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp
+--- a/dom/ipc/ContentChild.cpp
++++ b/dom/ipc/ContentChild.cpp
+@@ -168,44 +168,41 @@
+ #include "mozilla/X11Util.h"
+ #endif
+ 
+ #ifdef ACCESSIBILITY
+ #include "nsAccessibilityService.h"
+ #endif
+ 
+ #include "mozilla/dom/File.h"
+-#include "mozilla/dom/devicestorage/DeviceStorageRequestChild.h"
+ #include "mozilla/dom/PPresentationChild.h"
+ #include "mozilla/dom/PresentationIPCService.h"
+ #include "mozilla/ipc/InputStreamUtils.h"
+ 
+ #ifdef MOZ_WEBSPEECH
+ #include "mozilla/dom/PSpeechSynthesisChild.h"
+ #endif
+ 
+ #include "ProcessUtils.h"
+ #include "URIUtils.h"
+ #include "nsContentUtils.h"
+ #include "nsIPrincipal.h"
+-#include "nsDeviceStorage.h"
+ #include "DomainPolicy.h"
+ #include "mozilla/dom/ipc/StructuredCloneData.h"
+ #include "mozilla/dom/time/DateCacheCleaner.h"
+ #include "mozilla/net/NeckoMessageUtils.h"
+ #include "mozilla/widget/PuppetBidiKeyboard.h"
+ #include "mozilla/RemoteSpellCheckEngineChild.h"
+ #include "GMPServiceChild.h"
+ #include "gfxPlatform.h"
+ #include "nscore.h" // for NS_FREE_PERMANENT_DATA
+ #include "VRManagerChild.h"
+ 
+ using namespace mozilla;
+ using namespace mozilla::docshell;
+-using namespace mozilla::dom::devicestorage;
+ using namespace mozilla::dom::ipc;
+ using namespace mozilla::dom::workers;
+ using namespace mozilla::media;
+ using namespace mozilla::embedding;
+ using namespace mozilla::gmp;
+ using namespace mozilla::hal_sandbox;
+ using namespace mozilla::ipc;
+ using namespace mozilla::layers;
+@@ -1806,29 +1803,16 @@ ContentChild::GetCPOWManager()
+ }
+ 
+ bool
+ ContentChild::RecvPTestShellConstructor(PTestShellChild* actor)
+ {
+   return true;
+ }
+ 
+-PDeviceStorageRequestChild*
+-ContentChild::AllocPDeviceStorageRequestChild(const DeviceStorageParams& aParams)
+-{
+-  return new DeviceStorageRequestChild();
+-}
+-
+-bool
+-ContentChild::DeallocPDeviceStorageRequestChild(PDeviceStorageRequestChild* aDeviceStorage)
+-{
+-  delete aDeviceStorage;
+-  return true;
+-}
+-
+ PNeckoChild*
+ ContentChild::AllocPNeckoChild()
+ {
+   return new NeckoChild();
+ }
+ 
+ bool
+ ContentChild::DeallocPNeckoChild(PNeckoChild* necko)
+@@ -2531,38 +2515,16 @@ ContentChild::RecvVolumes(nsTArray<Volum
+   if (vs) {
+     vs->RecvVolumesFromParent(aVolumes);
+   }
+ #endif
+   return true;
+ }
+ 
+ bool
+-ContentChild::RecvFilePathUpdate(const nsString& aStorageType,
+-                                 const nsString& aStorageName,
+-                                 const nsString& aPath,
+-                                 const nsCString& aReason)
+-{
+-  if (nsDOMDeviceStorage::InstanceCount() == 0) {
+-    // No device storage instances in this process. Don't try and
+-    // and create a DeviceStorageFile since it will fail.
+-
+-    return true;
+-  }
+-
+-  RefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(aStorageType, aStorageName, aPath);
+-
+-  nsString reason;
+-  CopyASCIItoUTF16(aReason, reason);
+-  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
+-  obs->NotifyObservers(dsf, "file-watcher-update", reason.get());
+-  return true;
+-}
+-
+-bool
+ ContentChild::RecvFileSystemUpdate(const nsString& aFsName,
+                                    const nsString& aVolumeName,
+                                    const int32_t& aState,
+                                    const int32_t& aMountGeneration,
+                                    const bool& aIsMediaPresent,
+                                    const bool& aIsSharing,
+                                    const bool& aIsFormatting,
+                                    const bool& aIsFake,
+diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h
+--- a/dom/ipc/ContentChild.h
++++ b/dom/ipc/ContentChild.h
+@@ -193,22 +193,16 @@ public:
+                                             const IPCTabContext& aContext,
+                                             const uint32_t& aChromeFlags,
+                                             const ContentParentId& aCpID,
+                                             const bool& aIsForApp,
+                                             const bool& aIsForBrowser) override;
+ 
+   virtual bool DeallocPBrowserChild(PBrowserChild*) override;
+ 
+-  virtual PDeviceStorageRequestChild*
+-  AllocPDeviceStorageRequestChild(const DeviceStorageParams&) override;
+-
+-  virtual bool
+-  DeallocPDeviceStorageRequestChild(PDeviceStorageRequestChild*) override;
+-
+   virtual PBlobChild*
+   AllocPBlobChild(const BlobConstructorParams& aParams) override;
+ 
+   virtual bool DeallocPBlobChild(PBlobChild* aActor) override;
+ 
+   virtual PCrashReporterChild*
+   AllocPCrashReporterChild(const mozilla::dom::NativeThreadId& id,
+                            const uint32_t& processType) override;
+@@ -436,21 +430,16 @@ public:
+ 
+   virtual bool
+   RecvInitBlobURLs(nsTArray<BlobURLRegistrationData>&& aRegistations) override;
+ 
+   virtual bool RecvLastPrivateDocShellDestroyed() override;
+ 
+   virtual bool RecvVolumes(InfallibleTArray<VolumeInfo>&& aVolumes) override;
+ 
+-  virtual bool RecvFilePathUpdate(const nsString& aStorageType,
+-                                  const nsString& aStorageName,
+-                                  const nsString& aPath,
+-                                  const nsCString& aReason) override;
+-
+   virtual bool RecvFileSystemUpdate(const nsString& aFsName,
+                                     const nsString& aVolumeName,
+                                     const int32_t& aState,
+                                     const int32_t& aMountGeneration,
+                                     const bool& aIsMediaPresent,
+                                     const bool& aIsSharing,
+                                     const bool& aIsFormatting,
+                                     const bool& aIsFake,
+diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp
+--- a/dom/ipc/ContentParent.cpp
++++ b/dom/ipc/ContentParent.cpp
+@@ -23,17 +23,16 @@
+ 
+ #include "chrome/common/process_watcher.h"
+ 
+ #include "mozilla/a11y/PDocAccessible.h"
+ #include "AppProcessChecker.h"
+ #include "AudioChannelService.h"
+ #include "BlobParent.h"
+ #include "CrashReporterParent.h"
+-#include "DeviceStorageStatics.h"
+ #include "GMPServiceParent.h"
+ #include "HandlerServiceParent.h"
+ #include "IHistory.h"
+ #include "imgIContainer.h"
+ #include "mozIApplication.h"
+ #if defined(XP_WIN) && defined(ACCESSIBILITY)
+ #include "mozilla/a11y/AccessibleWrap.h"
+ #endif
+@@ -50,17 +49,16 @@
+ #include "mozilla/dom/GetFilesHelper.h"
+ #include "mozilla/dom/GeolocationBinding.h"
+ #include "mozilla/dom/Notification.h"
+ #include "mozilla/dom/PContentBridgeParent.h"
+ #include "mozilla/dom/PContentPermissionRequestParent.h"
+ #include "mozilla/dom/PCycleCollectWithLogsParent.h"
+ #include "mozilla/dom/PMemoryReportRequestParent.h"
+ #include "mozilla/dom/ServiceWorkerRegistrar.h"
+-#include "mozilla/dom/devicestorage/DeviceStorageRequestParent.h"
+ #include "mozilla/dom/power/PowerManagerService.h"
+ #include "mozilla/dom/Permissions.h"
+ #include "mozilla/dom/PresentationParent.h"
+ #include "mozilla/dom/PPresentationParent.h"
+ #include "mozilla/dom/PushNotifier.h"
+ #include "mozilla/dom/FlyWebPublishedServerIPC.h"
+ #include "mozilla/dom/quota/QuotaManagerService.h"
+ #include "mozilla/dom/time/DateCacheCleaner.h"
+@@ -272,17 +270,16 @@ using base::ChildPrivileges;
+ using base::KillProcess;
+ #ifdef MOZ_ENABLE_PROFILER_SPS
+ using mozilla::ProfileGatherer;
+ #endif
+ 
+ #ifdef MOZ_CRASHREPORTER
+ using namespace CrashReporter;
+ #endif
+-using namespace mozilla::dom::devicestorage;
+ using namespace mozilla::dom::power;
+ using namespace mozilla::media;
+ using namespace mozilla::embedding;
+ using namespace mozilla::gfx;
+ using namespace mozilla::gmp;
+ using namespace mozilla::hal;
+ using namespace mozilla::ipc;
+ using namespace mozilla::layers;
+@@ -2775,22 +2772,16 @@ ContentParent::Observe(nsISupports* aSub
+     Unused << SendCycleCollect();
+   }
+   else if (!strcmp(aTopic, "child-mmu-request")){
+     Unused << SendMinimizeMemoryUsage();
+   }
+   else if (!strcmp(aTopic, "last-pb-context-exited")) {
+     Unused << SendLastPrivateDocShellDestroyed();
+   }
+-  else if (!strcmp(aTopic, "file-watcher-update")) {
+-    nsCString creason;
+-    CopyUTF16toUTF8(aData, creason);
+-    DeviceStorageFile* file = static_cast<DeviceStorageFile*>(aSubject);
+-    Unused << SendFilePathUpdate(file->mStorageType, file->mStorageName, file->mPath, creason);
+-  }
+ #ifdef MOZ_WIDGET_GONK
+   else if(!strcmp(aTopic, NS_VOLUME_STATE_CHANGED)) {
+     nsCOMPtr<nsIVolume> vol = do_QueryInterface(aSubject);
+     if (!vol) {
+       return NS_ERROR_NOT_AVAILABLE;
+     }
+ 
+     nsString volName;
+@@ -3021,35 +3012,16 @@ ContentParent::AllocPBrowserParent(const
+ }
+ 
+ bool
+ ContentParent::DeallocPBrowserParent(PBrowserParent* frame)
+ {
+   return nsIContentParent::DeallocPBrowserParent(frame);
+ }
+ 
+-PDeviceStorageRequestParent*
+-ContentParent::AllocPDeviceStorageRequestParent(const DeviceStorageParams& aParams)
+-{
+-  RefPtr<DeviceStorageRequestParent> result = new DeviceStorageRequestParent(aParams);
+-  if (!result->EnsureRequiredPermissions(this)) {
+-    return nullptr;
+-  }
+-  result->Dispatch();
+-  return result.forget().take();
+-}
+-
+-bool
+-ContentParent::DeallocPDeviceStorageRequestParent(PDeviceStorageRequestParent* doomed)
+-{
+-  DeviceStorageRequestParent *parent = static_cast<DeviceStorageRequestParent*>(doomed);
+-  NS_RELEASE(parent);
+-  return true;
+-}
+-
+ PBlobParent*
+ ContentParent::AllocPBlobParent(const BlobConstructorParams& aParams)
+ {
+   return nsIContentParent::AllocPBlobParent(aParams);
+ }
+ 
+ bool
+ ContentParent::DeallocPBlobParent(PBlobParent* aActor)
+@@ -3871,35 +3843,16 @@ ContentParent::RecvAsyncMessage(const ns
+                                 InfallibleTArray<CpowEntry>&& aCpows,
+                                 const IPC::Principal& aPrincipal,
+                                 const ClonedMessageData& aData)
+ {
+   return nsIContentParent::RecvAsyncMessage(aMsg, Move(aCpows), aPrincipal,
+                                             aData);
+ }
+ 
+-bool
+-ContentParent::RecvFilePathUpdateNotify(const nsString& aType,
+-                                        const nsString& aStorageName,
+-                                        const nsString& aFilePath,
+-                                        const nsCString& aReason)
+-{
+-  RefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(aType,
+-                                                        aStorageName,
+-                                                        aFilePath);
+-
+-  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
+-  if (!obs) {
+-    return false;
+-  }
+-  obs->NotifyObservers(dsf, "file-watcher-update",
+-                       NS_ConvertASCIItoUTF16(aReason).get());
+-  return true;
+-}
+-
+ static int32_t
+ AddGeolocationListener(nsIDOMGeoPositionCallback* watcher,
+                        nsIDOMGeoPositionErrorCallback* errorCallBack,
+                        bool highAccuracy)
+ {
+   nsCOMPtr<nsIDOMGeoGeolocation> geo = do_GetService("@mozilla.org/geolocation;1");
+   if (!geo) {
+     return -1;
+@@ -4943,35 +4896,16 @@ ContentParent::RecvBeginDriverCrashGuard
+ bool
+ ContentParent::RecvEndDriverCrashGuard(const uint32_t& aGuardType)
+ {
+   mDriverCrashGuard = nullptr;
+   return true;
+ }
+ 
+ bool
+-ContentParent::RecvGetDeviceStorageLocation(const nsString& aType,
+-                                            nsString* aPath)
+-{
+-#ifdef MOZ_WIDGET_ANDROID
+-  mozilla::AndroidBridge::GetExternalPublicDirectory(aType, *aPath);
+-  return true;
+-#else
+-  return false;
+-#endif
+-}
+-
+-bool
+-ContentParent::RecvGetDeviceStorageLocations(DeviceStorageLocationInfo* info)
+-{
+-    DeviceStorageStatics::GetDeviceStorageLocationsForIPC(info);
+-    return true;
+-}
+-
+-bool
+ ContentParent::RecvGetAndroidSystemInfo(AndroidSystemInfo* aInfo)
+ {
+ #ifdef MOZ_WIDGET_ANDROID
+   nsSystemInfo::GetAndroidSystemInfo(aInfo);
+   return true;
+ #else
+   MOZ_CRASH("wrong platform!");
+   return false;
+diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h
+--- a/dom/ipc/ContentParent.h
++++ b/dom/ipc/ContentParent.h
+@@ -726,22 +726,16 @@ private:
+                                               const IPCTabContext& aContext,
+                                               const uint32_t& aChromeFlags,
+                                               const ContentParentId& aCpId,
+                                               const bool& aIsForApp,
+                                               const bool& aIsForBrowser) override;
+ 
+   virtual bool DeallocPBrowserParent(PBrowserParent* frame) override;
+ 
+-  virtual PDeviceStorageRequestParent*
+-  AllocPDeviceStorageRequestParent(const DeviceStorageParams&) override;
+-
+-  virtual bool
+-  DeallocPDeviceStorageRequestParent(PDeviceStorageRequestParent*) override;
+-
+   virtual PBlobParent*
+   AllocPBlobParent(const BlobConstructorParams& aParams) override;
+ 
+   virtual bool DeallocPBlobParent(PBlobParent* aActor) override;
+ 
+   virtual bool
+   RecvPBlobConstructor(PBlobParent* aActor,
+                        const BlobConstructorParams& params) override;
+@@ -927,21 +921,16 @@ private:
+                               const IPC::Principal& aPrincipal,
+                               nsTArray<StructuredCloneData>* aRetvals) override;
+ 
+   virtual bool RecvAsyncMessage(const nsString& aMsg,
+                                 InfallibleTArray<CpowEntry>&& aCpows,
+                                 const IPC::Principal& aPrincipal,
+                                 const ClonedMessageData& aData) override;
+ 
+-  virtual bool RecvFilePathUpdateNotify(const nsString& aType,
+-                                        const nsString& aStorageName,
+-                                        const nsString& aFilePath,
+-                                        const nsCString& aReason) override;
+-
+   virtual bool RecvAddGeolocationListener(const IPC::Principal& aPrincipal,
+                                           const bool& aHighAccuracy) override;
+   virtual bool RecvRemoveGeolocationListener() override;
+ 
+   virtual bool RecvSetGeolocationHigherAccuracy(const bool& aEnable) override;
+ 
+   virtual bool RecvConsoleMessage(const nsString& aMessage) override;
+ 
+@@ -1047,21 +1036,16 @@ private:
+                                     const uint32_t& aDropEffect) override;
+ 
+   virtual bool RecvProfile(const nsCString& aProfile) override;
+ 
+   virtual bool RecvGetGraphicsDeviceInitData(ContentDeviceData* aOut) override;
+ 
+   void StartProfiler(nsIProfilerStartParams* aParams);
+ 
+-  virtual bool RecvGetDeviceStorageLocation(const nsString& aType,
+-                                            nsString* aPath) override;
+-
+-  virtual bool RecvGetDeviceStorageLocations(DeviceStorageLocationInfo* info) override;
+-
+   virtual bool RecvGetAndroidSystemInfo(AndroidSystemInfo* aInfo) override;
+ 
+   virtual bool RecvNotifyBenchmarkResult(const nsString& aCodecName,
+                                          const uint32_t& aDecodeFPS) override;
+ 
+   virtual bool RecvNotifyPushObservers(const nsCString& aScope,
+                                        const IPC::Principal& aPrincipal,
+                                        const nsString& aMessageId) override;
+diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl
+--- a/dom/ipc/PContent.ipdl
++++ b/dom/ipc/PContent.ipdl
+@@ -10,17 +10,16 @@ include protocol PBrowser;
+ include protocol PCompositorBridge;
+ include protocol PContentBridge;
+ include protocol PContentPermissionRequest;
+ include protocol PCycleCollectWithLogs;
+ include protocol PCrashReporter;
+ include protocol PPSMContentDownloader;
+ include protocol PExternalHelperApp;
+ include protocol PHandlerService;
+-include protocol PDeviceStorageRequest;
+ include protocol PFileDescriptorSet;
+ include protocol PHal;
+ include protocol PHeapSnapshotTempFileHelper;
+ include protocol PProcessHangMonitor;
+ include protocol PImageBridge;
+ include protocol PMedia;
+ include protocol PMemoryReportRequest;
+ include protocol PNecko;
+@@ -111,130 +110,16 @@ struct FontListEntry {
+     nsCString filepath;
+     uint16_t  weight;
+     int16_t   stretch;
+     uint8_t   italic;
+     uint8_t   index;
+     bool      isHidden;
+ };
+ 
+-struct DeviceStorageFreeSpaceParams
+-{
+-  nsString type;
+-  nsString storageName;
+-};
+-
+-struct DeviceStorageUsedSpaceParams
+-{
+-  nsString type;
+-  nsString storageName;
+-};
+-
+-struct DeviceStorageAvailableParams
+-{
+-  nsString type;
+-  nsString storageName;
+-};
+-
+-struct DeviceStorageStatusParams
+-{
+-  nsString type;
+-  nsString storageName;
+-};
+-
+-struct DeviceStorageFormatParams
+-{
+-  nsString type;
+-  nsString storageName;
+-};
+-
+-struct DeviceStorageMountParams
+-{
+-  nsString type;
+-  nsString storageName;
+-};
+-
+-struct DeviceStorageUnmountParams
+-{
+-  nsString type;
+-  nsString storageName;
+-};
+-
+-struct DeviceStorageAddParams
+-{
+-  nsString type;
+-  nsString storageName;
+-  nsString relpath;
+-  PBlob blob;
+-};
+-
+-struct DeviceStorageAppendParams
+-{
+-  nsString type;
+-  nsString storageName;
+-  nsString relpath;
+-  PBlob blob;
+-};
+-
+-struct DeviceStorageCreateFdParams
+-{
+-  nsString type;
+-  nsString storageName;
+-  nsString relpath;
+-};
+-
+-struct DeviceStorageGetParams
+-{
+-  nsString type;
+-  nsString storageName;
+-  nsString rootDir;
+-  nsString relpath;
+-};
+-
+-struct DeviceStorageDeleteParams
+-{
+-  nsString type;
+-  nsString storageName;
+-  nsString relpath;
+-};
+-
+-struct DeviceStorageEnumerationParams
+-{
+-  nsString type;
+-  nsString storageName;
+-  nsString rootdir;
+-  uint64_t since;
+-};
+-
+-union DeviceStorageParams
+-{
+-  DeviceStorageAddParams;
+-  DeviceStorageAppendParams;
+-  DeviceStorageCreateFdParams;
+-  DeviceStorageGetParams;
+-  DeviceStorageDeleteParams;
+-  DeviceStorageEnumerationParams;
+-  DeviceStorageFreeSpaceParams;
+-  DeviceStorageUsedSpaceParams;
+-  DeviceStorageAvailableParams;
+-  DeviceStorageStatusParams;
+-  DeviceStorageFormatParams;
+-  DeviceStorageMountParams;
+-  DeviceStorageUnmountParams;
+-};
+-
+-struct DeviceStorageLocationInfo {
+-  nsString music;
+-  nsString pictures;
+-  nsString videos;
+-  nsString sdcard;
+-  nsString apps;
+-  nsString crashes;
+-};
+-
+ union PrefValue {
+   nsCString;
+   int32_t;
+   bool;
+ };
+ 
+ union MaybePrefValue {
+   PrefValue;
+@@ -355,17 +240,16 @@ nested(upto inside_cpow) sync protocol P
+     parent opens PGMPService;
+     child opens PBackground;
+ 
+     manages PBlob;
+     manages PBrowser;
+     manages PContentPermissionRequest;
+     manages PCrashReporter;
+     manages PCycleCollectWithLogs;
+-    manages PDeviceStorageRequest;
+     manages PPSMContentDownloader;
+     manages PExternalHelperApp;
+     manages PFileDescriptorSet;
+     manages PHal;
+     manages PHandlerService;
+     manages PHeapSnapshotTempFileHelper;
+     manages PMedia;
+     manages PMemoryReportRequest;
+@@ -538,19 +422,16 @@ child:
+     /**
+      * Send BlobURLRegistrationData to child process.
+      */
+     async InitBlobURLs(BlobURLRegistrationData[] registrations);
+ 
+     // Notify child that last-pb-context-exited notification was observed
+     async LastPrivateDocShellDestroyed();
+ 
+-    async FilePathUpdate(nsString storageType, nsString storageName, nsString filepath,
+-                         nsCString reasons);
+-
+     // Note: Any changes to this structure should also be changed in
+     // VolumeInfo above.
+     async FileSystemUpdate(nsString fsName, nsString mountPoint, int32_t fsState,
+                            int32_t mountGeneration, bool isMediaPresent,
+                            bool isSharing, bool isFormatting, bool isFake,
+                            bool isUnmounting, bool isRemovable, bool isHotSwappable);
+ 
+     // Notify volume is removed.
+@@ -738,17 +619,16 @@ parent:
+      * process. |newPluginEpoch| is the current epoch in the chrome process. If
+      * |pluginEpoch == newPluginEpoch|, then |plugins| will be left empty.
+      */
+     sync FindPlugins(uint32_t pluginEpoch) returns (nsresult aResult, PluginTag[] plugins, uint32_t newPluginEpoch);
+ 
+     async PJavaScript();
+ 
+     async PRemoteSpellcheckEngine();
+-    async PDeviceStorageRequest(DeviceStorageParams params);
+ 
+     sync PCrashReporter(NativeThreadId tid, uint32_t processType);
+ 
+     /**
+      * Is this token compatible with the provided version?
+      *
+      * |version| The offered version to test
+      * Returns |True| if the offered version is compatible
+@@ -921,21 +801,16 @@ parent:
+     async FirstIdle();
+ 
+     async AudioChannelServiceStatus(bool aActiveTelephonyChannel,
+                                     bool aContentOrNormalChannel,
+                                     bool aAnyActiveChannel);
+ 
+     async AudioChannelChangeDefVolChannel(int32_t aChannel, bool aHidden);
+ 
+-    async FilePathUpdateNotify(nsString aType,
+-                               nsString aStorageName,
+-                               nsString aFilepath,
+-                               nsCString aReason);
+-
+     // called by the child (test code only) to propagate volume changes to the parent
+     async CreateFakeVolume(nsString fsName, nsString mountPoint);
+     async SetFakeVolumeState(nsString fsName, int32_t fsState);
+     async RemoveFakeVolume(nsString fsName);
+ 
+     sync KeywordToURI(nsCString keyword)
+         returns (nsString providerName, OptionalInputStreamParams postData, OptionalURIParams uri);
+ 
+@@ -1108,22 +983,16 @@ parent:
+                       float aFullZoom)
+       returns (nsresult rv,
+                bool windowOpened,
+                FrameScriptInfo[] frameScripts,
+                nsCString urlToLoad,
+                TextureFactoryIdentifier textureFactoryIdentifier,
+                uint64_t layersId);
+ 
+-    sync GetDeviceStorageLocation(nsString type)
+-        returns (nsString path);
+-
+-    sync GetDeviceStorageLocations()
+-	returns (DeviceStorageLocationInfo info);
+-
+     sync GetAndroidSystemInfo()
+         returns (AndroidSystemInfo info);
+ 
+     /**
+      * Tells the parent to ungrab the pointer on the default display.
+      *
+      * This is for GTK platforms where we have to ensure the pointer ungrab happens in the
+      * chrome process as that's the process that receives the pointer event.
+diff --git a/dom/ipc/moz.build b/dom/ipc/moz.build
+--- a/dom/ipc/moz.build
++++ b/dom/ipc/moz.build
+@@ -120,17 +120,16 @@ if CONFIG['MOZ_CONTENT_SANDBOX'] and CON
+         'mozsandbox',
+     ]
+ 
+ LOCAL_INCLUDES += [
+     '/caps',
+     '/chrome',
+     '/docshell/base',
+     '/dom/base',
+-    '/dom/devicestorage',
+     '/dom/events',
+     '/dom/filesystem',
+     '/dom/geolocation',
+     '/dom/media/webspeech/synth/ipc',
+     '/dom/security',
+     '/dom/storage',
+     '/dom/workers',
+     '/embedding/components/printingui/ipc',
+diff --git a/dom/moz.build b/dom/moz.build
+--- a/dom/moz.build
++++ b/dom/moz.build
+@@ -42,17 +42,16 @@ DIRS += [
+     'base',
+     'archivereader',
+     'bindings',
+     'battery',
+     'browser-element',
+     'cache',
+     'canvas',
+     'crypto',
+-    'devicestorage',
+     'encoding',
+     'events',
+     'fetch',
+     'filehandle',
+     'filesystem',
+     'flyweb',
+     'gamepad',
+     'geolocation',
+diff --git a/dom/webidl/DeviceStorage.webidl b/dom/webidl/DeviceStorage.webidl
+deleted file mode 100644
+--- a/dom/webidl/DeviceStorage.webidl
++++ /dev/null
+@@ -1,95 +0,0 @@
+-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+-/* This Source Code Form is subject to the terms of the Mozilla Public
+- * License, v. 2.0. If a copy of the MPL was not distributed with this
+- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+-
+-dictionary DeviceStorageEnumerationParameters {
+-  Date since;
+-};
+-
+-[Pref="device.storage.enabled"]
+-interface DeviceStorage : EventTarget {
+-  attribute EventHandler onchange;
+-
+-  [Throws]
+-  DOMRequest? add(Blob? aBlob);
+-  [Throws]
+-  DOMRequest? addNamed(Blob? aBlob, DOMString aName);
+-
+-  /**
+-   * Append data to a given file.
+-   * If the file doesn't exist, a "NotFoundError" event will be dispatched.
+-   * In the same time, it is a request.onerror case.
+-   * If the file exists, it will be opened with the following permission:
+-   *                                                "PR_WRONLY|PR_CREATE_FILE|PR_APPEND".
+-   * The function will return null when blob file is null and other unexpected situations.
+-   * @parameter aBlob: A Blob object representing the data to append
+-   * @parameter aName: A string representing the full name (path + file name) of the file
+-   *                   to append data to.
+-   */
+-  [Throws]
+-  DOMRequest? appendNamed(Blob? aBlob, DOMString aName);
+-
+-  [Throws]
+-  DOMRequest get(DOMString aName);
+-  [Throws]
+-  DOMRequest getEditable(DOMString aName);
+-  [Throws]
+-  DOMRequest delete(DOMString aName);
+-
+-  [Throws]
+-  DOMCursor enumerate(optional DeviceStorageEnumerationParameters options);
+-  [Throws]
+-  DOMCursor enumerate(DOMString path,
+-                      optional DeviceStorageEnumerationParameters options);
+-  [Throws]
+-  DOMCursor enumerateEditable(optional DeviceStorageEnumerationParameters options);
+-  [Throws]
+-  DOMCursor enumerateEditable(DOMString path,
+-                              optional DeviceStorageEnumerationParameters options);
+-
+-  [Throws]
+-  DOMRequest freeSpace();
+-  [Throws]
+-  DOMRequest usedSpace();
+-  [Throws]
+-  DOMRequest available();
+-  [Throws]
+-  DOMRequest storageStatus();
+-  [Throws]
+-  DOMRequest format();
+-  [Throws]
+-  DOMRequest mount();
+-  [Throws]
+-  DOMRequest unmount();
+-
+-  // Note that the storageName is just a name (like sdcard), and doesn't
+-  // include any path information.
+-  readonly attribute DOMString storageName;
+-
+-  // Indicates if the storage area denoted by storageName is capable of
+-  // being mounted and unmounted.
+-  readonly attribute boolean canBeMounted;
+-
+-  // Indicates if the storage area denoted by storageName is capable of
+-  // being shared and unshared.
+-  readonly attribute boolean canBeShared;
+-
+-  // Indicates if the storage area denoted by storageName is capable of
+-  // being formatted.
+-  readonly attribute boolean canBeFormatted;
+-
+-  // Determines if this storage area is the one which will be used by default
+-  // for storing new files.
+-  readonly attribute boolean default;
+-
+-  // Indicates if the storage area denoted by storageName is removable
+-  readonly attribute boolean isRemovable;
+-
+-  // True if the storage area is close to being full
+-  readonly attribute boolean lowDiskSpace;
+-
+-  [NewObject]
+-  // XXXbz what type does this really return?
+-  Promise<any> getRoot();
+-};
+diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build
+--- a/dom/webidl/moz.build
++++ b/dom/webidl/moz.build
+@@ -104,17 +104,16 @@ WEBIDL_FILES = [
+     'DataTransfer.webidl',
+     'DataTransferItem.webidl',
+     'DataTransferItemList.webidl',
+     'DecoderDoctorNotification.webidl',
+     'DedicatedWorkerGlobalScope.webidl',
+     'DelayNode.webidl',
+     'DesktopNotification.webidl',
+     'DeviceMotionEvent.webidl',
+-    'DeviceStorage.webidl',
+     'Directory.webidl',
+     'Document.webidl',
+     'DocumentFragment.webidl',
+     'DocumentTimeline.webidl',
+     'DocumentType.webidl',
+     'DOMCursor.webidl',
+     'DOMError.webidl',
+     'DOMException.webidl',
+diff --git a/layout/build/nsLayoutStatics.cpp b/layout/build/nsLayoutStatics.cpp
+--- a/layout/build/nsLayoutStatics.cpp
++++ b/layout/build/nsLayoutStatics.cpp
+@@ -122,17 +122,16 @@ using namespace mozilla::system;
+ #include "mozilla/dom/CustomElementRegistry.h"
+ #include "mozilla/dom/time/DateCacheCleaner.h"
+ #include "mozilla/EventDispatcher.h"
+ #include "mozilla/IMEStateManager.h"
+ #include "mozilla/dom/HTMLVideoElement.h"
+ #include "TouchManager.h"
+ #include "MediaDecoder.h"
+ #include "MediaPrefs.h"
+-#include "mozilla/dom/devicestorage/DeviceStorageStatics.h"
+ #include "mozilla/ServoBindings.h"
+ #include "mozilla/StaticPresData.h"
+ #include "mozilla/dom/WebIDLGlobalNameHash.h"
+ 
+ using namespace mozilla;
+ using namespace mozilla::net;
+ using namespace mozilla::dom;
+ using namespace mozilla::dom::ipc;
+@@ -303,18 +302,16 @@ nsLayoutStatics::Initialize()
+   nsStyleContext::Initialize();
+   mozilla::LayerAnimationInfo::Initialize();
+ #endif
+ 
+   MediaDecoder::InitStatics();
+ 
+   PromiseDebugging::Init();
+ 
+-  mozilla::dom::devicestorage::DeviceStorageStatics::Initialize();
+-
+   mozilla::dom::WebCryptoThreadPool::Initialize();
+ 
+   // NB: We initialize servo in nsAppRunner.cpp, because we need to do it after
+   // creating the hidden DOM window to support some current stylo hacks. We
+   // should move initialization back here once those go away.
+ 
+ #ifndef MOZ_WIDGET_ANDROID
+   // On Android, we instantiate it when constructing AndroidBridge.
+diff --git a/mobile/android/components/ContentPermissionPrompt.js b/mobile/android/components/ContentPermissionPrompt.js
+--- a/mobile/android/components/ContentPermissionPrompt.js
++++ b/mobile/android/components/ContentPermissionPrompt.js
+@@ -8,20 +8,16 @@ const Cu = Components.utils;
+ const Cc = Components.classes;
+ 
+ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+ Cu.import("resource://gre/modules/Services.jsm");
+ 
+ const kEntities = {
+   "contacts": "contacts",
+   "desktop-notification": "desktopNotification2",
+-  "device-storage:music": "deviceStorageMusic",
+-  "device-storage:pictures": "deviceStoragePictures",
+-  "device-storage:sdcard": "deviceStorageSdcard",
+-  "device-storage:videos": "deviceStorageVideos",
+   "geolocation": "geolocation",
+   "flyweb-publish-server": "flyWebPublishServer",
+ };
+ 
+ // For these types, prompt for permission if action is unknown.
+ const PROMPT_FOR_UNKNOWN = [
+   "desktop-notification",
+   "geolocation",
+diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
+--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
++++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java
+@@ -2198,54 +2198,16 @@ public class GeckoAppShell
+         return null;
+     }
+ 
+     @WrapForJNI
+     private static String connectionGetMimeType(URLConnection connection) {
+         return connection.getContentType();
+     }
+ 
+-    /**
+-     * Retrieve the absolute path of an external storage directory.
+-     *
+-     * @param type The type of directory to return
+-     * @return Absolute path of the specified directory or null on failure
+-     */
+-    @WrapForJNI(calledFrom = "gecko")
+-    private static String getExternalPublicDirectory(final String type) {
+-        final String state = Environment.getExternalStorageState();
+-        if (!Environment.MEDIA_MOUNTED.equals(state) &&
+-            !Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+-            // External storage is not available.
+-            return null;
+-        }
+-
+-        if ("sdcard".equals(type)) {
+-            // SD card has a separate path.
+-            return Environment.getExternalStorageDirectory().getAbsolutePath();
+-        }
+-
+-        final String systemType;
+-        if ("downloads".equals(type)) {
+-            systemType = Environment.DIRECTORY_DOWNLOADS;
+-        } else if ("pictures".equals(type)) {
+-            systemType = Environment.DIRECTORY_PICTURES;
+-        } else if ("videos".equals(type)) {
+-            systemType = Environment.DIRECTORY_MOVIES;
+-        } else if ("music".equals(type)) {
+-            systemType = Environment.DIRECTORY_MUSIC;
+-        } else if ("apps".equals(type)) {
+-            File appInternalStorageDirectory = getApplicationContext().getFilesDir();
+-            return new File(appInternalStorageDirectory, "mozilla").getAbsolutePath();
+-        } else {
+-            return null;
+-        }
+-        return Environment.getExternalStoragePublicDirectory(systemType).getAbsolutePath();
+-    }
+-
+     @WrapForJNI(calledFrom = "gecko")
+     private static int getMaxTouchPoints() {
+         PackageManager pm = getApplicationContext().getPackageManager();
+         if (pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_JAZZHAND)) {
+             // at least, 5+ fingers.
+             return 5;
+         } else if (pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT)) {
+             // at least, 2+ fingers.
+diff --git a/netwerk/test/mochitests/signed_web_packaged_app.sjs b/netwerk/test/mochitests/signed_web_packaged_app.sjs
+--- a/netwerk/test/mochitests/signed_web_packaged_app.sjs
++++ b/netwerk/test/mochitests/signed_web_packaged_app.sjs
+@@ -35,19 +35,16 @@ Content-Type: application/x-web-app-mani
+       "src": "scripts/library.js",
+       "integrity": "TN2ByXZiaBiBCvS4MeZ02UyNi44vED+KjdjLInUl4o8="
+     }
+   ],
+   "moz-permissions": [
+     {
+       "systemXHR": {
+         "description": "Needed to download stuff"
+-      },
+-      "devicestorage:pictures": {
+-        "description": "Need to load pictures"
+       }
+     }
+   ],
+   "package-identifier": "09bc9714-7ab6-4320-9d20-fde4c237522c",
+   "description": "A great app!"
+ }\r
+ --NKWXJUAFXB\r
+ Content-Location: page2.html\r
+diff --git a/toolkit/components/jsdownloads/src/DownloadIntegration.jsm b/toolkit/components/jsdownloads/src/DownloadIntegration.jsm
+--- a/toolkit/components/jsdownloads/src/DownloadIntegration.jsm
++++ b/toolkit/components/jsdownloads/src/DownloadIntegration.jsm
+@@ -268,53 +268,16 @@ this.DownloadIntegration = {
+     // Add the view used for detecting changes to downloads to be persisted.
+     // We must do this after the list of persistent downloads has been loaded,
+     // even if the load operation failed. We wait for a complete initialization
+     // so other callers cannot modify the list without being detected. The
+     // DownloadAutoSaveView is kept alive by the underlying DownloadList.
+     yield new DownloadAutoSaveView(list, this._store).initialize();
+   }),
+ 
+-#ifdef MOZ_WIDGET_GONK
+-  /**
+-    * Finds the default download directory which can be either in the
+-    * internal storage or on the sdcard.
+-    *
+-    * @return {Promise}
+-    * @resolves The downloads directory string path.
+-    */
+-  _getDefaultDownloadDirectory: Task.async(function* () {
+-    let directoryPath;
+-    let win = Services.wm.getMostRecentWindow("navigator:browser");
+-    let storages = win.navigator.getDeviceStorages("sdcard");
+-    let preferredStorageName;
+-    // Use the first one or the default storage.
+-    storages.forEach((aStorage) => {
+-      if (aStorage.default || !preferredStorageName) {
+-        preferredStorageName = aStorage.storageName;
+-      }
+-    });
+-
+-    // Now get the path for this storage area.
+-    if (preferredStorageName) {
+-      let volume = volumeService.getVolumeByName(preferredStorageName);
+-      if (volume && volume.state === Ci.nsIVolume.STATE_MOUNTED){
+-        directoryPath = OS.Path.join(volume.mountPoint, "downloads");
+-        yield OS.File.makeDir(directoryPath, { ignoreExisting: true });
+-      }
+-    }
+-    if (directoryPath) {
+-      return directoryPath;
+-    } else {
+-      throw new Components.Exception("No suitable storage for downloads.",
+-                                     Cr.NS_ERROR_FILE_UNRECOGNIZED_PATH);
+-    }
+-  }),
+-#endif
+-
+   /**
+    * Determines if a Download object from the list of persistent downloads
+    * should be saved into a file, so that it can be restored across sessions.
+    *
+    * This function allows filtering out downloads that the host application is
+    * not interested in persisting across sessions, for example downloads that
+    * finished successfully.
+    *
+@@ -377,18 +340,16 @@ this.DownloadIntegration = {
+ #ifdef MOZ_WIDGET_ANDROID
+     // Android doesn't have a $HOME directory, and by default we only have
+     // write access to /data/data/org.mozilla.{$APP} and /sdcard
+     directoryPath = gEnvironment.get("DOWNLOADS_DIRECTORY");
+     if (!directoryPath) {
+       throw new Components.Exception("DOWNLOADS_DIRECTORY is not set.",
+                                      Cr.NS_ERROR_FILE_UNRECOGNIZED_PATH);
+     }
+-#elifdef MOZ_WIDGET_GONK
+-    directoryPath = this._getDefaultDownloadDirectory();
+ #else
+     // For Linux, use XDG download dir, with a fallback to Home/Downloads
+     // if the XDG user dirs are disabled.
+     try {
+       directoryPath = this._getDirectory("DfltDwnld");
+     } catch(e) {
+       directoryPath = yield this._createDownloadsDirectory("Home");
+     }
+@@ -405,19 +366,16 @@ this.DownloadIntegration = {
+   /**
+    * Returns the user downloads directory asynchronously.
+    *
+    * @return {Promise}
+    * @resolves The downloads directory string path.
+    */
+   getPreferredDownloadsDirectory: Task.async(function* () {
+     let directoryPath = null;
+-#ifdef MOZ_WIDGET_GONK
+-    directoryPath = this._getDefaultDownloadDirectory();
+-#else
+     let prefValue = 1;
+ 
+     try {
+       prefValue = Services.prefs.getIntPref("browser.download.folderList");
+     } catch(e) {}
+ 
+     switch(prefValue) {
+       case 0: // Desktop
+@@ -435,17 +393,16 @@ this.DownloadIntegration = {
+         } catch(ex) {
+           // Either the preference isn't set or the directory cannot be created.
+           directoryPath = yield this.getSystemDownloadsDirectory();
+         }
+         break;
+       default:
+         directoryPath = yield this.getSystemDownloadsDirectory();
+     }
+-#endif
+     return directoryPath;
+   }),
+ 
+   /**
+    * Returns the temporary downloads directory asynchronously.
+    *
+    * @return {Promise}
+    * @resolves The downloads directory string path.
+diff --git a/toolkit/components/jsdownloads/src/DownloadPlatform.cpp b/toolkit/components/jsdownloads/src/DownloadPlatform.cpp
+--- a/toolkit/components/jsdownloads/src/DownloadPlatform.cpp
++++ b/toolkit/components/jsdownloads/src/DownloadPlatform.cpp
+@@ -185,28 +185,16 @@ nsresult DownloadPlatform::DownloadDone(
+       if (sourceCFURL) {
+         ::CFRelease(sourceCFURL);
+       }
+       if (referrerCFURL) {
+         ::CFRelease(referrerCFURL);
+       }
+     }
+ #endif
+-    if (mozilla::Preferences::GetBool("device.storage.enabled", true)) {
+-      // Tell DeviceStorage that a new file may have been added.
+-      nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
+-      nsCOMPtr<nsISupportsString> pathString
+-        = do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
+-      if (obs && pathString) {
+-        if (NS_SUCCEEDED(pathString->SetData(path))) {
+-          (void)obs->NotifyObservers(pathString, "download-watcher-notify",
+-                                     u"modified");
+-        }
+-      }
+-    }
+   }
+ 
+ #endif
+ 
+   return NS_OK;
+ }
+ 
+ nsresult DownloadPlatform::MapUrlToZone(const nsAString& aURL,
+diff --git a/toolkit/components/jsdownloads/test/unit/common_test_Download.js b/toolkit/components/jsdownloads/test/unit/common_test_Download.js
+--- a/toolkit/components/jsdownloads/test/unit/common_test_Download.js
++++ b/toolkit/components/jsdownloads/test/unit/common_test_Download.js
+@@ -2315,103 +2315,16 @@ add_task(function* test_toSerializable_s
+   let download2 = yield Downloads.createDownload(reserialized);
+ 
+   do_check_eq(download1.startTime.constructor.name, "Date");
+   do_check_eq(download2.startTime.constructor.name, "Date");
+   do_check_eq(download1.startTime.toJSON(), download2.startTime.toJSON());
+ });
+ 
+ /**
+- * This test will call the platform specific operations within
+- * DownloadPlatform::DownloadDone. While there is no test to verify the
+- * specific behaviours, this at least ensures that there is no error or crash.
+- */
+-add_task(function* test_platform_integration()
+-{
+-  let downloadFiles = [];
+-  let oldDeviceStorageEnabled = false;
+-  try {
+-     oldDeviceStorageEnabled = Services.prefs.getBoolPref("device.storage.enabled");
+-  } catch (e) {
+-    // This happens if the pref doesn't exist.
+-  }
+-  let downloadWatcherNotified = false;
+-  let observer = {
+-    observe: function(subject, topic, data) {
+-      do_check_eq(topic, "download-watcher-notify");
+-      do_check_eq(data, "modified");
+-      downloadWatcherNotified = true;
+-    }
+-  }
+-  Services.obs.addObserver(observer, "download-watcher-notify", false);
+-  Services.prefs.setBoolPref("device.storage.enabled", true);
+-  let downloadDoneCalled = false;
+-  let monitorFn = base => ({
+-    __proto__: base,
+-    downloadDone() {
+-      return super.downloadDone(...arguments).then(() => {
+-        downloadDoneCalled = true;
+-      });
+-    },
+-  });
+-  Integration.downloads.register(monitorFn);
+-  DownloadIntegration.allowDirectories = true;
+-  function cleanup() {
+-    for (let file of downloadFiles) {
+-      file.remove(true);
+-    }
+-    Services.obs.removeObserver(observer, "download-watcher-notify");
+-    Services.prefs.setBoolPref("device.storage.enabled", oldDeviceStorageEnabled);
+-    Integration.downloads.unregister(monitorFn);
+-    DownloadIntegration.allowDirectories = false;
+-  }
+-
+-  for (let isPrivate of [false, true]) {
+-    downloadDoneCalled = false;
+-
+-    // Some platform specific operations only operate on files outside the
+-    // temporary directory or in the Downloads directory (such as setting
+-    // the Windows searchable attribute, and the Mac Downloads icon bouncing),
+-    // so use the system Downloads directory for the target file.
+-    let targetFilePath = yield DownloadIntegration.getSystemDownloadsDirectory();
+-    targetFilePath = OS.Path.join(targetFilePath,
+-                                  "test" + (Math.floor(Math.random() * 1000000)));
+-    let targetFile = new FileUtils.File(targetFilePath);
+-    downloadFiles.push(targetFile);
+-
+-    let download;
+-    if (gUseLegacySaver) {
+-      download = yield promiseStartLegacyDownload(httpUrl("source.txt"),
+-                                                  { isPrivate, targetFile });
+-    }
+-    else {
+-      download = yield Downloads.createDownload({
+-        source: { url: httpUrl("source.txt"), isPrivate },
+-        target: targetFile,
+-      });
+-      download.start().catch(() => {});
+-    }
+-
+-    // Wait for the whenSucceeded promise to be resolved first.
+-    // downloadDone should be called before the whenSucceeded promise is resolved.
+-    yield download.whenSucceeded().then(function () {
+-      do_check_true(downloadDoneCalled);
+-      do_check_true(downloadWatcherNotified);
+-    });
+-
+-    // Then, wait for the promise returned by "start" to be resolved.
+-    yield promiseDownloadStopped(download);
+-
+-    yield promiseVerifyTarget(download.target, TEST_DATA_SHORT);
+-  }
+-
+-  cleanup();
+-});
+-
+-/**
+  * Checks that downloads are added to browsing history when they start.
+  */
+ add_task(function* test_history()
+ {
+   mustInterruptResponses();
+ 
+   // We will wait for the visit to be notified during the download.
+   yield PlacesTestUtils.clearHistory();
+diff --git a/toolkit/content/devicestorage.properties b/toolkit/content/devicestorage.properties
+deleted file mode 100644
+--- a/toolkit/content/devicestorage.properties
++++ /dev/null
+@@ -1,4 +0,0 @@
+-# Extensions we recognize for DeviceStorage storage areas
+-pictures=*.jpe; *.jpg; *.jpeg; *.gif; *.png; *.bmp;
+-music=*.mp3; *.oga; *.ogg; *.m4a; *.m4b; *.m4p; *.m4r; *.3gp; *.3gpp; *.mp4; *.m3u; *.pls; *.opus; *.amr; *.wav; *.lcka; *.mka; *.flac;
+-videos=*.mp4; *.mpeg; *.mpg; *.ogv; *.ogx; *.webm; *.3gp; *.3gpp; *.3g2; *.ogg; *.m4v; *.ts; *.m2ts; *.avi; *.divx; *.mkv;
+diff --git a/toolkit/content/jar.mn b/toolkit/content/jar.mn
+--- a/toolkit/content/jar.mn
++++ b/toolkit/content/jar.mn
+@@ -40,17 +40,16 @@ toolkit.jar:
+    content/global/browser-content.js
+ *   content/global/buildconfig.html
+    content/global/contentAreaUtils.js
+ #ifndef MOZ_ICECATMOBILE
+    content/global/customizeToolbar.css
+    content/global/customizeToolbar.js
+    content/global/customizeToolbar.xul
+ #endif
+-   content/global/devicestorage.properties
+ #ifndef MOZ_ICECATMOBILE
+    content/global/editMenuOverlay.js
+ *  content/global/editMenuOverlay.xul
+    content/global/finddialog.js
+ *  content/global/finddialog.xul
+    content/global/findUtils.js
+ #endif
+    content/global/filepicker.properties
+@@ -113,9 +112,9 @@ toolkit.jar:
+    content/global/bindings/videocontrols.css   (widgets/videocontrols.css)
+ *  content/global/bindings/wizard.xml          (widgets/wizard.xml)
+ #ifdef XP_MACOSX
+    content/global/macWindowMenu.js
+ #endif
+    content/global/svg/svgBindings.xml          (/layout/svg/resources/content/svgBindings.xml)
+    content/global/gmp-sources/eme-adobe.json   (gmp-sources/eme-adobe.json)
+    content/global/gmp-sources/openh264.json    (gmp-sources/openh264.json)
+-   content/global/gmp-sources/widevinecdm.json (gmp-sources/widevinecdm.json)
+\ No newline at end of file
++   content/global/gmp-sources/widevinecdm.json (gmp-sources/widevinecdm.json)
+diff --git a/uriloader/exthandler/nsExternalHelperAppService.cpp b/uriloader/exthandler/nsExternalHelperAppService.cpp
+--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
++++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
+@@ -101,20 +101,16 @@
+ 
+ #ifdef MOZ_WIDGET_ANDROID
+ #include "IceCatMobileJNIWrappers.h"
+ #endif
+ 
+ #include "mozilla/Preferences.h"
+ #include "mozilla/ipc/URIUtils.h"
+ 
+-#ifdef MOZ_WIDGET_GONK
+-#include "nsDeviceStorage.h"
+-#endif
+-
+ using namespace mozilla;
+ using namespace mozilla::ipc;
+ 
+ // Download Folder location constants
+ #define NS_PREF_DOWNLOAD_DIR        "browser.download.dir"
+ #define NS_PREF_DOWNLOAD_FOLDERLIST "browser.download.folderList"
+ enum {
+   NS_FOLDER_VALUE_DESKTOP = 0
+@@ -321,65 +317,16 @@ static nsresult GetDownloadDirectory(nsI
+   }
+ 
+   if (!dir) {
+     // If not, we default to the OS X default download location.
+     nsresult rv = NS_GetSpecialDirectory(NS_OSX_DEFAULT_DOWNLOAD_DIR,
+                                          getter_AddRefs(dir));
+     NS_ENSURE_SUCCESS(rv, rv);
+   }
+-#elif defined(MOZ_WIDGET_GONK)
+-  // On Gonk, store the files on the sdcard in the downloads directory.
+-  // We need to check with the volume manager which storage point is
+-  // available.
+-
+-  // Pick the default storage in case multiple (internal and external) ones
+-  // are available.
+-  nsString storageName;
+-  nsDOMDeviceStorage::GetDefaultStorageName(NS_LITERAL_STRING("sdcard"),
+-                                            storageName);
+-
+-  RefPtr<DeviceStorageFile> dsf(
+-    new DeviceStorageFile(NS_LITERAL_STRING("sdcard"),
+-                          storageName,
+-                          NS_LITERAL_STRING("downloads")));
+-  NS_ENSURE_TRUE(dsf->mFile, NS_ERROR_FILE_ACCESS_DENIED);
+-
+-  // If we're not checking for availability we're done.
+-  if (aSkipChecks) {
+-    dsf->mFile.forget(_directory);
+-    return NS_OK;
+-  }
+-
+-  // Check device storage status before continuing.
+-  nsString storageStatus;
+-  dsf->GetStatus(storageStatus);
+-
+-  // If we get an "unavailable" status, it means the sd card is not present.
+-  // We'll also catch internal errors by looking for an empty string and assume
+-  // the SD card isn't present when this occurs.
+-  if (storageStatus.EqualsLiteral("unavailable") ||
+-      storageStatus.IsEmpty()) {
+-    return NS_ERROR_FILE_NOT_FOUND;
+-  }
+-
+-  // If we get a status other than 'available' here it means the card is busy
+-  // because it's mounted via USB or it is being formatted.
+-  if (!storageStatus.EqualsLiteral("available")) {
+-    return NS_ERROR_FILE_ACCESS_DENIED;
+-  }
+-
+-  bool alreadyThere;
+-  nsresult rv = dsf->mFile->Exists(&alreadyThere);
+-  NS_ENSURE_SUCCESS(rv, rv);
+-  if (!alreadyThere) {
+-    rv = dsf->mFile->Create(nsIFile::DIRECTORY_TYPE, 0770);
+-    NS_ENSURE_SUCCESS(rv, rv);
+-  }
+-  dir = dsf->mFile;
+ #elif defined(ANDROID)
+   // We ask Java for the temporary download directory. The directory will be
+   // different depending on whether we have the permission to write to the
+   // public download directory or not.
+   // In the case where we do not have the permission we will start the
+   // download to the app cache directory and later move it to the final
+   // destination after prompting for the permission.
+   jni::String::LocalRef downloadDir;
+diff --git a/widget/android/AndroidBridge.cpp b/widget/android/AndroidBridge.cpp
+--- a/widget/android/AndroidBridge.cpp
++++ b/widget/android/AndroidBridge.cpp
+@@ -1119,42 +1119,8 @@ nsresult AndroidBridge::InputStreamRead(
+ 
+     if (read <= 0) {
+         *aRead = 0;
+         return NS_OK;
+     }
+     *aRead = read;
+     return NS_OK;
+ }
+-
+-nsresult AndroidBridge::GetExternalPublicDirectory(const nsAString& aType, nsAString& aPath) {
+-    if (XRE_IsContentProcess()) {
+-        nsString key(aType);
+-        nsAutoString path;
+-        if (AndroidBridge::sStoragePaths.Get(key, &path)) {
+-            aPath = path;
+-            return NS_OK;
+-        }
+-
+-        // Lazily get the value from the parent.
+-        dom::ContentChild* child = dom::ContentChild::GetSingleton();
+-        if (child) {
+-          nsAutoString type(aType);
+-          child->SendGetDeviceStorageLocation(type, &path);
+-          if (!path.IsEmpty()) {
+-            AndroidBridge::sStoragePaths.Put(key, path);
+-            aPath = path;
+-            return NS_OK;
+-          }
+-        }
+-
+-        ALOG_BRIDGE("AndroidBridge::GetExternalPublicDirectory no cache for %s",
+-              NS_ConvertUTF16toUTF8(aType).get());
+-        return NS_ERROR_NOT_AVAILABLE;
+-    }
+-
+-    auto path = GeckoAppShell::GetExternalPublicDirectory(aType);
+-    if (!path) {
+-        return NS_ERROR_NOT_AVAILABLE;
+-    }
+-    aPath = path->ToString();
+-    return NS_OK;
+-}
+diff --git a/widget/android/AndroidBridge.h b/widget/android/AndroidBridge.h
+--- a/widget/android/AndroidBridge.h
++++ b/widget/android/AndroidBridge.h
+@@ -197,18 +197,16 @@ public:
+     static jmethodID GetStaticMethodID(JNIEnv* env, jclass jClass, const char* methodName, const char* methodType);
+ 
+     static jni::Object::LocalRef ChannelCreate(jni::Object::Param);
+ 
+     static void InputStreamClose(jni::Object::Param obj);
+     static uint32_t InputStreamAvailable(jni::Object::Param obj);
+     static nsresult InputStreamRead(jni::Object::Param obj, char *aBuf, uint32_t aCount, uint32_t *aRead);
+ 
+-    static nsresult GetExternalPublicDirectory(const nsAString& aType, nsAString& aPath);
+-
+ protected:
+     static nsDataHashtable<nsStringHashKey, nsString> sStoragePaths;
+ 
+     static AndroidBridge* sBridge;
+ 
+     AndroidBridge();
+     ~AndroidBridge();
+ 
+diff --git a/widget/android/GeneratedJNIWrappers.cpp b/widget/android/GeneratedJNIWrappers.cpp
+--- a/widget/android/GeneratedJNIWrappers.cpp
++++ b/widget/android/GeneratedJNIWrappers.cpp
+@@ -274,24 +274,16 @@ auto GeckoAppShell::GetExceptionStackTra
+ constexpr char GeckoAppShell::GetExtensionFromMimeType_t::name[];
+ constexpr char GeckoAppShell::GetExtensionFromMimeType_t::signature[];
+ 
+ auto GeckoAppShell::GetExtensionFromMimeType(mozilla::jni::String::Param a0) -> mozilla::jni::String::LocalRef
+ {
+     return mozilla::jni::Method<GetExtensionFromMimeType_t>::Call(GeckoAppShell::Context(), nullptr, a0);
+ }
+ 
+-constexpr char GeckoAppShell::GetExternalPublicDirectory_t::name[];
+-constexpr char GeckoAppShell::GetExternalPublicDirectory_t::signature[];
+-
+-auto GeckoAppShell::GetExternalPublicDirectory(mozilla::jni::String::Param a0) -> mozilla::jni::String::LocalRef
+-{
+-    return mozilla::jni::Method<GetExternalPublicDirectory_t>::Call(GeckoAppShell::Context(), nullptr, a0);
+-}
+-
+ constexpr char GeckoAppShell::GetHWDecoderCapability_t::name[];
+ constexpr char GeckoAppShell::GetHWDecoderCapability_t::signature[];
+ 
+ auto GeckoAppShell::GetHWDecoderCapability() -> bool
+ {
+     return mozilla::jni::Method<GetHWDecoderCapability_t>::Call(GeckoAppShell::Context(), nullptr);
+ }
+ 
+diff --git a/widget/android/GeneratedJNIWrappers.h b/widget/android/GeneratedJNIWrappers.h
+--- a/widget/android/GeneratedJNIWrappers.h
++++ b/widget/android/GeneratedJNIWrappers.h
+@@ -724,36 +724,16 @@ public:
+         static const mozilla::jni::CallingThread callingThread =
+                 mozilla::jni::CallingThread::GECKO;
+         static const mozilla::jni::DispatchTarget dispatchTarget =
+                 mozilla::jni::DispatchTarget::CURRENT;
+     };
+ 
+     static auto GetExtensionFromMimeType(mozilla::jni::String::Param) -> mozilla::jni::String::LocalRef;
+ 
+-    struct GetExternalPublicDirectory_t {
+-        typedef GeckoAppShell Owner;
+-        typedef mozilla::jni::String::LocalRef ReturnType;
+-        typedef mozilla::jni::String::Param SetterType;
+-        typedef mozilla::jni::Args<
+-                mozilla::jni::String::Param> Args;
+-        static constexpr char name[] = "getExternalPublicDirectory";
+-        static constexpr char signature[] =
+-                "(Ljava/lang/String;)Ljava/lang/String;";
+-        static const bool isStatic = true;
+-        static const mozilla::jni::ExceptionMode exceptionMode =
+-                mozilla::jni::ExceptionMode::ABORT;
+-        static const mozilla::jni::CallingThread callingThread =
+-                mozilla::jni::CallingThread::GECKO;
+-        static const mozilla::jni::DispatchTarget dispatchTarget =
+-                mozilla::jni::DispatchTarget::CURRENT;
+-    };
+-
+-    static auto GetExternalPublicDirectory(mozilla::jni::String::Param) -> mozilla::jni::String::LocalRef;
+-
+     struct GetHWDecoderCapability_t {
+         typedef GeckoAppShell Owner;
+         typedef bool ReturnType;
+         typedef bool SetterType;
+         typedef mozilla::jni::Args<> Args;
+         static constexpr char name[] = "getHWDecoderCapability";
+         static constexpr char signature[] =
+                 "()Z";
+diff --git a/xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp b/xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
+--- a/xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
++++ b/xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
+@@ -155,17 +155,16 @@
+ #include "mozilla/dom/CSSValueBinding.h"
+ #include "mozilla/dom/CSSValueListBinding.h"
+ #include "mozilla/dom/CustomEventBinding.h"
+ #ifdef MOZ_WEBRTC
+ #include "mozilla/dom/DataChannelBinding.h"
+ #endif
+ #include "mozilla/dom/DataContainerEventBinding.h"
+ #include "mozilla/dom/DataTransferBinding.h"
+-#include "mozilla/dom/DeviceStorageBinding.h"
+ #include "mozilla/dom/DOMCursorBinding.h"
+ #include "mozilla/dom/DOMExceptionBinding.h"
+ #include "mozilla/dom/DOMParserBinding.h"
+ #include "mozilla/dom/DOMRequestBinding.h"
+ #include "mozilla/dom/DocumentBinding.h"
+ #include "mozilla/dom/DocumentFragmentBinding.h"
+ #include "mozilla/dom/DocumentTypeBinding.h"
+ #include "mozilla/dom/DocumentBinding.h"
+
diff --git a/gnu/packages/patches/icu4c-CVE-2014-6585.patch b/gnu/packages/patches/icu4c-CVE-2014-6585.patch
deleted file mode 100644
index d21a0d0ba1..0000000000
--- a/gnu/packages/patches/icu4c-CVE-2014-6585.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-Copied from Debian.
-
-description: out-of-bounds read
-origin: https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2014-6585
-
---- a/source/layout/LETableReference.h
-+++ b/source/layout/LETableReference.h
-@@ -322,7 +322,12 @@ LE_TRACE_TR("INFO: new RTAO")
-   }
-   
-   const T& operator()(le_uint32 i, LEErrorCode &success) const {
--    return *getAlias(i,success);
-+    const T *ret = getAlias(i,success);
-+    if (LE_FAILURE(success) || ret==NULL) {
-+      return *(new T());
-+    } else {
-+      return *ret;
-+    }
-   }
- 
-   size_t getOffsetFor(le_uint32 i, LEErrorCode &success) const {
diff --git a/gnu/packages/patches/icu4c-CVE-2015-1270.patch b/gnu/packages/patches/icu4c-CVE-2015-1270.patch
deleted file mode 100644
index 2a7658d36e..0000000000
--- a/gnu/packages/patches/icu4c-CVE-2015-1270.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-Copied from Debian.
-
-diff --git a/source/common/ucnv_io.cpp b/source/common/ucnv_io.cpp
-index 5dd35d8..4424664 100644
---- a/source/common/ucnv_io.cpp
-+++ b/source/common/ucnv_io.cpp
-@@ -744,7 +744,7 @@ ucnv_io_getConverterName(const char *alias, UBool *containsOption, UErrorCode *p
-              * the name begins with 'x-'. If it does, strip it off and try
-              * again.  This behaviour is similar to how ICU4J does it.
-              */
--            if (aliasTmp[0] == 'x' || aliasTmp[1] == '-') {
-+            if (aliasTmp[0] == 'x' && aliasTmp[1] == '-') {
-                 aliasTmp = aliasTmp+2;
-             } else {
-                 break;
diff --git a/gnu/packages/patches/icu4c-CVE-2015-4760.patch b/gnu/packages/patches/icu4c-CVE-2015-4760.patch
deleted file mode 100644
index 77da283b7b..0000000000
--- a/gnu/packages/patches/icu4c-CVE-2015-4760.patch
+++ /dev/null
@@ -1,189 +0,0 @@
-Copied from Debian.
-
-Description: missing boundary checks in layout engine
- It was discovered that ICU Layout Engine was missing multiple boundary checks.
- These could lead to buffer overflows and memory corruption.  A specially
- crafted file could cause an application using ICU to parse untrusted font
- files to crash and, possibly, execute arbitrary code.
-Author: Laszlo Boszormenyi (GCS) <gcs@debian.org>
-Origin: upstream, http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/rev/3f9845510b47
-Reviewed-By: srl, bae, mschoene
-Forwarded: not-needed
-Last-Update: 2015-07-30
-
----
-
---- icu-52.1.orig/source/layout/ContextualGlyphInsertionProc2.cpp
-+++ icu-52.1/source/layout/ContextualGlyphInsertionProc2.cpp
-@@ -82,6 +82,10 @@ le_uint16 ContextualGlyphInsertionProces
-     
-     le_int16 markIndex = SWAPW(entry->markedInsertionListIndex);
-     if (markIndex > 0) {
-+        if (markGlyph < 0 || markGlyph >= glyphStorage.getGlyphCount()) {
-+           success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
-+           return 0;
-+        }
-         le_int16 count = (flags & cgiMarkedInsertCountMask) >> 5;
-         le_bool isKashidaLike = (flags & cgiMarkedIsKashidaLike);
-         le_bool isBefore = (flags & cgiMarkInsertBefore);
-@@ -90,6 +94,10 @@ le_uint16 ContextualGlyphInsertionProces
- 
-     le_int16 currIndex = SWAPW(entry->currentInsertionListIndex);
-     if (currIndex > 0) {
-+        if (currGlyph < 0 || currGlyph >= glyphStorage.getGlyphCount()) {
-+           success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
-+           return 0;
-+        }
-         le_int16 count = flags & cgiCurrentInsertCountMask;
-         le_bool isKashidaLike = (flags & cgiCurrentIsKashidaLike);
-         le_bool isBefore = (flags & cgiCurrentInsertBefore);
---- icu-52.1.orig/source/layout/ContextualGlyphSubstProc.cpp
-+++ icu-52.1/source/layout/ContextualGlyphSubstProc.cpp
-@@ -51,6 +51,10 @@ ByteOffset ContextualGlyphSubstitutionPr
-   WordOffset currOffset = SWAPW(entry->currOffset);
-   
-   if (markOffset != 0 && LE_SUCCESS(success)) {
-+    if (markGlyph < 0 || markGlyph >= glyphStorage.getGlyphCount()) {
-+       success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
-+       return 0;
-+    }
-     LEGlyphID mGlyph = glyphStorage[markGlyph];
-     TTGlyphID newGlyph = SWAPW(int16Table.getObject(markOffset + LE_GET_GLYPH(mGlyph), success)); // whew. 
- 
-@@ -58,6 +62,10 @@ ByteOffset ContextualGlyphSubstitutionPr
-   }
- 
-   if (currOffset != 0) {
-+    if (currGlyph < 0 || currGlyph >= glyphStorage.getGlyphCount()) {
-+       success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
-+       return 0;
-+    }
-     LEGlyphID thisGlyph = glyphStorage[currGlyph];
-     TTGlyphID newGlyph = SWAPW(int16Table.getObject(currOffset + LE_GET_GLYPH(thisGlyph), success)); // whew. 
-     
---- icu-52.1.orig/source/layout/ContextualGlyphSubstProc2.cpp
-+++ icu-52.1/source/layout/ContextualGlyphSubstProc2.cpp
-@@ -45,17 +45,25 @@ le_uint16 ContextualGlyphSubstitutionPro
-     if(LE_FAILURE(success)) return 0;
-     le_uint16 newState = SWAPW(entry->newStateIndex);
-     le_uint16 flags = SWAPW(entry->flags);
--    le_int16 markIndex = SWAPW(entry->markIndex);
--    le_int16 currIndex = SWAPW(entry->currIndex);
-+    le_uint16 markIndex = SWAPW(entry->markIndex);
-+    le_uint16 currIndex = SWAPW(entry->currIndex);
-     
--    if (markIndex != -1) {
-+    if (markIndex != 0x0FFFF) {
-+        if (markGlyph < 0 || markGlyph >= glyphStorage.getGlyphCount()) {
-+           success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
-+           return 0;
-+        }
-         le_uint32 offset = SWAPL(perGlyphTable(markIndex, success));
-         LEGlyphID mGlyph = glyphStorage[markGlyph];
-         TTGlyphID newGlyph = lookup(offset, mGlyph, success);        
-         glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
-     }
- 
--    if (currIndex != -1) {
-+    if (currIndex != 0x0FFFF) {
-+        if (currGlyph < 0 || currGlyph >= glyphStorage.getGlyphCount()) {
-+           success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
-+           return 0;
-+        }
-         le_uint32 offset = SWAPL(perGlyphTable(currIndex, success));
-         LEGlyphID thisGlyph = glyphStorage[currGlyph];
-         TTGlyphID newGlyph = lookup(offset, thisGlyph, success);
---- icu-52.1.orig/source/layout/IndicRearrangementProcessor.cpp
-+++ icu-52.1/source/layout/IndicRearrangementProcessor.cpp
-@@ -45,6 +45,11 @@ ByteOffset IndicRearrangementProcessor::
-     ByteOffset newState = SWAPW(entry->newStateOffset);
-     IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
- 
-+    if (currGlyph < 0 || currGlyph >= glyphStorage.getGlyphCount()) {
-+       success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
-+       return 0;
-+    }
-+
-     if (flags & irfMarkFirst) {
-         firstGlyph = currGlyph;
-     }
---- icu-52.1.orig/source/layout/IndicRearrangementProcessor2.cpp
-+++ icu-52.1/source/layout/IndicRearrangementProcessor2.cpp
-@@ -43,6 +43,11 @@ le_uint16 IndicRearrangementProcessor2::
-     le_uint16 newState = SWAPW(entry->newStateIndex); // index to the new state
-     IndicRearrangementFlags  flags =  (IndicRearrangementFlags) SWAPW(entry->flags);
-     
-+    if (currGlyph < 0 || currGlyph >= glyphStorage.getGlyphCount()) {
-+       success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
-+       return 0;
-+    }
-+
-     if (flags & irfMarkFirst) {
-         firstGlyph = currGlyph;
-     }
---- icu-52.1.orig/source/layout/LigatureSubstProc.cpp
-+++ icu-52.1/source/layout/LigatureSubstProc.cpp
-@@ -48,7 +48,7 @@ ByteOffset LigatureSubstitutionProcessor
-   const LigatureSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
- 
-     ByteOffset newState = SWAPW(entry->newStateOffset);
--    le_int16 flags = SWAPW(entry->flags);
-+    le_uint16 flags = SWAPW(entry->flags);
- 
-     if (flags & lsfSetComponent) {
-         if (++m >= nComponents) {
---- icu-52.1.orig/source/layout/StateTableProcessor.cpp
-+++ icu-52.1/source/layout/StateTableProcessor.cpp
-@@ -60,6 +60,7 @@ void StateTableProcessor::process(LEGlyp
-         if (currGlyph == glyphCount) {
-             // XXX: How do we handle EOT vs. EOL?
-             classCode = classCodeEOT;
-+            break;
-         } else {
-             TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(glyphStorage[currGlyph]);
- 
---- icu-52.1.orig/source/layout/StateTableProcessor2.cpp
-+++ icu-52.1/source/layout/StateTableProcessor2.cpp
-@@ -78,6 +78,7 @@ void StateTableProcessor2::process(LEGly
-                 if (currGlyph == glyphCount || currGlyph == -1) {
-                     // XXX: How do we handle EOT vs. EOL?
-                     classCode = classCodeEOT;
-+                    break;
-                 } else {
-                     LEGlyphID gid = glyphStorage[currGlyph];
-                     TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
-@@ -109,6 +110,7 @@ void StateTableProcessor2::process(LEGly
-                 if (currGlyph == glyphCount || currGlyph == -1) {
-                     // XXX: How do we handle EOT vs. EOL?
-                     classCode = classCodeEOT;
-+                    break;
-                 } else {
-                     LEGlyphID gid = glyphStorage[currGlyph];
-                     TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
-@@ -146,6 +148,7 @@ void StateTableProcessor2::process(LEGly
-                 if (currGlyph == glyphCount || currGlyph == -1) {
-                     // XXX: How do we handle EOT vs. EOL?
-                     classCode = classCodeEOT;
-+                    break;
-                 } else if(currGlyph > glyphCount) {
-                   // note if > glyphCount, we've run off the end (bad font)
-                   currGlyph = glyphCount;
-@@ -186,6 +189,7 @@ void StateTableProcessor2::process(LEGly
-                 if (currGlyph == glyphCount || currGlyph == -1) {
-                     // XXX: How do we handle EOT vs. EOL?
-                     classCode = classCodeEOT;
-+                    break;
-                 } else {
-                     TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(glyphStorage[currGlyph]);
-                     if (glyphCode == 0xFFFF) {
---- icu-52.1.orig/source/layout/StateTables.h
-+++ icu-52.1/source/layout/StateTables.h
-@@ -101,7 +101,7 @@ typedef le_uint8 EntryTableIndex;
- struct StateEntry
- {
-     ByteOffset  newStateOffset;
--    le_int16    flags;
-+    le_uint16    flags;
- };
- 
- typedef le_uint16 EntryTableIndex2;
diff --git a/gnu/packages/patches/icu4c-CVE-2017-7867-CVE-2017-7868.patch b/gnu/packages/patches/icu4c-CVE-2017-7867-CVE-2017-7868.patch
new file mode 100644
index 0000000000..4db8f27998
--- /dev/null
+++ b/gnu/packages/patches/icu4c-CVE-2017-7867-CVE-2017-7868.patch
@@ -0,0 +1,164 @@
+Fix CVE-2017-7867 and CVE-2017-7868:
+
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-7867
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-7868
+
+Patch copied from upstream source repository:
+
+http://bugs.icu-project.org/trac/changeset/39671
+
+Index: icu/source/common/utext.cpp
+===================================================================
+--- icu/source/common/utext.cpp	(revision 39670)
++++ icu/source/common/utext.cpp	(revision 39671)
+@@ -848,7 +848,13 @@
+ 
+ // Chunk size.
+-//     Must be less than 85, because of byte mapping from UChar indexes to native indexes.
+-//     Worst case is three native bytes to one UChar.  (Supplemenaries are 4 native bytes
+-//     to two UChars.)
++//     Must be less than 42  (256/6), because of byte mapping from UChar indexes to native indexes.
++//     Worst case there are six UTF-8 bytes per UChar.
++//         obsolete 6 byte form fd + 5 trails maps to fffd
++//         obsolete 5 byte form fc + 4 trails maps to fffd
++//         non-shortest 4 byte forms maps to fffd
++//         normal supplementaries map to a pair of utf-16, two utf8 bytes per utf-16 unit
++//     mapToUChars array size must allow for the worst case, 6.
++//     This could be brought down to 4, by treating fd and fc as pure illegal,
++//     rather than obsolete lead bytes. But that is not compatible with the utf-8 access macros.
+ //
+ enum { UTF8_TEXT_CHUNK_SIZE=32 };
+@@ -890,5 +896,5 @@
+                                                      //    one for a supplementary starting in the last normal position,
+                                                      //    and one for an entry for the buffer limit position.
+-    uint8_t   mapToUChars[UTF8_TEXT_CHUNK_SIZE*3+6]; // Map native offset from bufNativeStart to
++    uint8_t   mapToUChars[UTF8_TEXT_CHUNK_SIZE*6+6]; // Map native offset from bufNativeStart to
+                                                      //   correspoding offset in filled part of buf.
+     int32_t   align;
+@@ -1033,4 +1039,5 @@
+             u8b = (UTF8Buf *)ut->p;   // the current buffer
+             mapIndex = ix - u8b->toUCharsMapStart;
++            U_ASSERT(mapIndex < (int32_t)sizeof(UTF8Buf::mapToUChars));
+             ut->chunkOffset = u8b->mapToUChars[mapIndex] - u8b->bufStartIdx;
+             return TRUE;
+@@ -1299,4 +1306,8 @@
+         //   If index is at the end, there is no character there to look at.
+         if (ix != ut->b) {
++            // Note: this function will only move the index back if it is on a trail byte
++            //       and there is a preceding lead byte and the sequence from the lead 
++            //       through this trail could be part of a valid UTF-8 sequence
++            //       Otherwise the index remains unchanged.
+             U8_SET_CP_START(s8, 0, ix);
+         }
+@@ -1312,5 +1323,8 @@
+         uint8_t *mapToNative = u8b->mapToNative;
+         uint8_t *mapToUChars = u8b->mapToUChars;
+-        int32_t  toUCharsMapStart = ix - (UTF8_TEXT_CHUNK_SIZE*3 + 1);
++        int32_t  toUCharsMapStart = ix - sizeof(UTF8Buf::mapToUChars) + 1;
++        // Note that toUCharsMapStart can be negative. Happens when the remaining
++        // text from current position to the beginning is less than the buffer size.
++        // + 1 because mapToUChars must have a slot at the end for the bufNativeLimit entry.
+         int32_t  destIx = UTF8_TEXT_CHUNK_SIZE+2;   // Start in the overflow region
+                                                     //   at end of buffer to leave room
+@@ -1339,4 +1353,5 @@
+                 // Special case ASCII range for speed.
+                 buf[destIx] = (UChar)c;
++                U_ASSERT(toUCharsMapStart <= srcIx);
+                 mapToUChars[srcIx - toUCharsMapStart] = (uint8_t)destIx;
+                 mapToNative[destIx] = (uint8_t)(srcIx - toUCharsMapStart);
+@@ -1368,4 +1383,5 @@
+                     mapToUChars[sIx-- - toUCharsMapStart] = (uint8_t)destIx;
+                 } while (sIx >= srcIx);
++                U_ASSERT(toUCharsMapStart <= (srcIx+1));
+ 
+                 // Set native indexing limit to be the current position.
+@@ -1542,4 +1558,5 @@
+     U_ASSERT(index<=ut->chunkNativeLimit);
+     int32_t mapIndex = index - u8b->toUCharsMapStart;
++    U_ASSERT(mapIndex < (int32_t)sizeof(UTF8Buf::mapToUChars));
+     int32_t offset = u8b->mapToUChars[mapIndex] - u8b->bufStartIdx;
+     U_ASSERT(offset>=0 && offset<=ut->chunkLength);
+Index: icu/source/test/intltest/utxttest.cpp
+===================================================================
+--- icu/source/test/intltest/utxttest.cpp	(revision 39670)
++++ icu/source/test/intltest/utxttest.cpp	(revision 39671)
+@@ -68,4 +68,6 @@
+         case 7: name = "Ticket12130";
+             if (exec) Ticket12130(); break;
++        case 8: name = "Ticket12888";
++            if (exec) Ticket12888(); break;
+         default: name = "";          break;
+     }
+@@ -1584,2 +1586,62 @@
+     utext_close(&ut);
+ }
++
++// Ticket 12888: bad handling of illegal utf-8 containing many instances of the archaic, now illegal,
++//               six byte utf-8 forms. Original implementation had an assumption that
++//               there would be at most three utf-8 bytes per UTF-16 code unit.
++//               The five and six byte sequences map to a single replacement character.
++
++void UTextTest::Ticket12888() {
++    const char *badString = 
++            "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++            "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++            "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++            "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++            "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++            "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++            "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++            "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++            "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++            "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++            "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++            "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++            "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++            "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++            "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++            "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++            "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++            "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++            "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80"
++            "\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80\xfd\x80\x80\x80\x80\x80";
++
++    UErrorCode status = U_ZERO_ERROR;
++    LocalUTextPointer ut(utext_openUTF8(NULL, badString, -1, &status));
++    TEST_SUCCESS(status);
++    for (;;) {
++        UChar32 c = utext_next32(ut.getAlias());
++        if (c == U_SENTINEL) {
++            break;
++        }
++    }
++    int32_t endIdx = utext_getNativeIndex(ut.getAlias());
++    if (endIdx != (int32_t)strlen(badString)) {
++        errln("%s:%d expected=%d, actual=%d", __FILE__, __LINE__, strlen(badString), endIdx);
++        return;
++    }
++
++    for (int32_t prevIndex = endIdx; prevIndex>0;) {
++        UChar32 c = utext_previous32(ut.getAlias());
++        int32_t currentIndex = utext_getNativeIndex(ut.getAlias());
++        if (c != 0xfffd) {
++            errln("%s:%d (expected, actual, index) = (%d, %d, %d)\n",
++                    __FILE__, __LINE__, 0xfffd, c, currentIndex);
++            break;
++        }
++        if (currentIndex != prevIndex - 6) {
++            errln("%s:%d: wrong index. Expected, actual = %d, %d",
++                    __FILE__, __LINE__, prevIndex - 6, currentIndex);
++            break;
++        }
++        prevIndex = currentIndex;
++    }
++}
+Index: icu/source/test/intltest/utxttest.h
+===================================================================
+--- icu/source/test/intltest/utxttest.h	(revision 39670)
++++ icu/source/test/intltest/utxttest.h	(revision 39671)
+@@ -39,4 +39,5 @@
+     void Ticket10983();
+     void Ticket12130();
++    void Ticket12888();
+ 
+ private:
diff --git a/gnu/packages/patches/libbase-fix-includes.patch b/gnu/packages/patches/libbase-fix-includes.patch
new file mode 100644
index 0000000000..3071a0c400
--- /dev/null
+++ b/gnu/packages/patches/libbase-fix-includes.patch
@@ -0,0 +1,71 @@
+This patch fixes the build of adb on linux.
+
+Copied from archlinux repository:
+https://git.archlinux.org/svntogit/community.git/tree/trunk/fix_build.patch?h=packages/android-tools
+
+diff --git a/adb/sysdeps.h b/adb/sysdeps.h
+index 75dcc86..867f3ec 100644
+--- a/adb/sysdeps.h
++++ b/adb/sysdeps.h
+@@ -25,6 +25,7 @@
+ #endif
+ 
+ #include <errno.h>
++#include <sys/syscall.h>
+ 
+ #include <string>
+ #include <vector>
+@@ -831,7 +832,16 @@ static __inline__ int adb_is_absolute_host_path(const char* path) {
+ 
+ static __inline__ unsigned long adb_thread_id()
+ {
+-    return (unsigned long)gettid();
++  // TODO: this function should be merged with GetThreadId
++#if defined(__BIONIC__)
++  return gettid();
++#elif defined(__APPLE__)
++  return syscall(SYS_thread_selfid);
++#elif defined(__linux__)
++  return syscall(__NR_gettid);
++#elif defined(_WIN32)
++  return GetCurrentThreadId();
++#endif
+ }
+ 
+ #endif /* !_WIN32 */
+diff --git a/base/errors_unix.cpp b/base/errors_unix.cpp
+index 296995e..48269b6 100644
+--- a/base/errors_unix.cpp
++++ b/base/errors_unix.cpp
+@@ -17,6 +17,7 @@
+ #include "android-base/errors.h"
+ 
+ #include <errno.h>
++#include <string.h>
+ 
+ namespace android {
+ namespace base {
+diff --git a/base/file.cpp b/base/file.cpp
+index da1adba..91a3901 100644
+--- a/base/file.cpp
++++ b/base/file.cpp
+@@ -20,6 +20,7 @@
+ #include <fcntl.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
++#include <string.h>
+ 
+ #include <string>
+ 
+diff --git a/base/logging.cpp b/base/logging.cpp
+index 1741871..e97c7f1 100644
+--- a/base/logging.cpp
++++ b/base/logging.cpp
+@@ -21,6 +21,7 @@
+ #include "android-base/logging.h"
+ 
+ #include <libgen.h>
++#include <string.h>
+ 
+ // For getprogname(3) or program_invocation_short_name.
+ #if defined(__ANDROID__) || defined(__APPLE__)
diff --git a/gnu/packages/patches/libbase-use-own-logging.patch b/gnu/packages/patches/libbase-use-own-logging.patch
new file mode 100644
index 0000000000..f755bf9722
--- /dev/null
+++ b/gnu/packages/patches/libbase-use-own-logging.patch
@@ -0,0 +1,80 @@
+Patch copied from:
+https://android.googlesource.com/platform/system/core/+/e5dd71a290f664d3f3bf0dd8a4bad411dc7ad416
+
+From e5dd71a290f664d3f3bf0dd8a4bad411dc7ad416 Mon Sep 17 00:00:00 2001
+From: Elliott Hughes <enh@google.com>
+Date: Thu, 28 Jul 2016 15:15:28 -0700
+Subject: [PATCH] libbase should use its own logging!
+
+Not doing so led to us using a bogus log tag.
+
+Bug: http://b/30281203
+Change-Id: I3ac91758a1a043146c65f2ae0f36fcfbe372c30f
+---
+ base/file.cpp    | 11 +++++------
+ base/logging.cpp |  3 +--
+ 2 files changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/base/file.cpp b/base/file.cpp
+index da1adba19..4e7ac82d1 100644
+--- a/base/file.cpp
++++ b/base/file.cpp
+@@ -24,9 +24,8 @@
+ #include <string>
+ 
+ #include "android-base/macros.h"  // For TEMP_FAILURE_RETRY on Darwin.
++#include "android-base/logging.h"
+ #include "android-base/utf8.h"
+-#define LOG_TAG "base.file"
+-#include "cutils/log.h"
+ #include "utils/Compat.h"
+ 
+ namespace android {
+@@ -86,22 +85,22 @@ bool WriteStringToFile(const std::string& content, const std::string& path,
+   int flags = O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW | O_BINARY;
+   int fd = TEMP_FAILURE_RETRY(open(path.c_str(), flags, mode));
+   if (fd == -1) {
+-    ALOGE("android::WriteStringToFile open failed: %s", strerror(errno));
++    PLOG(ERROR) << "android::WriteStringToFile open failed";
+     return false;
+   }
+ 
+   // We do an explicit fchmod here because we assume that the caller really
+   // meant what they said and doesn't want the umask-influenced mode.
+   if (fchmod(fd, mode) == -1) {
+-    ALOGE("android::WriteStringToFile fchmod failed: %s", strerror(errno));
++    PLOG(ERROR) << "android::WriteStringToFile fchmod failed";
+     return CleanUpAfterFailedWrite(path);
+   }
+   if (fchown(fd, owner, group) == -1) {
+-    ALOGE("android::WriteStringToFile fchown failed: %s", strerror(errno));
++    PLOG(ERROR) << "android::WriteStringToFile fchown failed";
+     return CleanUpAfterFailedWrite(path);
+   }
+   if (!WriteStringToFd(content, fd)) {
+-    ALOGE("android::WriteStringToFile write failed: %s", strerror(errno));
++    PLOG(ERROR) << "android::WriteStringToFile write failed";
+     return CleanUpAfterFailedWrite(path);
+   }
+   close(fd);
+diff --git a/base/logging.cpp b/base/logging.cpp
+index 769c266c9..959bb8b05 100644
+--- a/base/logging.cpp
++++ b/base/logging.cpp
+@@ -43,12 +43,11 @@
+ 
+ #include "android-base/macros.h"
+ #include "android-base/strings.h"
+-#include "cutils/threads.h"
+ 
+ // Headers for LogMessage::LogLine.
+ #ifdef __ANDROID__
+ #include <android/set_abort_message.h>
+-#include "cutils/log.h"
++#include "log/log.h"
+ #else
+ #include <sys/types.h>
+ #include <unistd.h>
+-- 
+2.11.0
+
diff --git a/gnu/packages/patches/mplayer2-theora-fix.patch b/gnu/packages/patches/mplayer2-theora-fix.patch
deleted file mode 100644
index 982db5f57c..0000000000
--- a/gnu/packages/patches/mplayer2-theora-fix.patch
+++ /dev/null
@@ -1,286 +0,0 @@
-Fix libtheora linking issue with modern theora versions.
-
-Adapted from:
-http://git.buildroot.net/buildroot/commit/?id=46b71cb0be27c0e6b7c93afb49fc80779bf310e3
-
---- a/libmpcodecs/vd_theora.c
-+++ b/libmpcodecs/vd_theora.c
-@@ -39,22 +39,23 @@
- 
- LIBVD_EXTERN(theora)
- 
--#include <theora/theora.h>
-+#include <theora/theoradec.h>
- 
- #define THEORA_NUM_HEADER_PACKETS 3
- 
- typedef struct theora_struct_st {
--    theora_state st;
--    theora_comment cc;
--    theora_info inf;
-+    th_setup_info *tsi;
-+    th_dec_ctx    *tctx;
-+    th_comment     tc;
-+    th_info        ti;
- } theora_struct_t;
- 
- /** Convert Theora pixelformat to the corresponding IMGFMT_ */
--static uint32_t theora_pixelformat2imgfmt(theora_pixelformat fmt){
-+static uint32_t theora_pixelformat2imgfmt(th_pixel_fmt fmt){
-     switch(fmt) {
--       case OC_PF_420: return IMGFMT_YV12;
--       case OC_PF_422: return IMGFMT_422P;
--       case OC_PF_444: return IMGFMT_444P;
-+       case TH_PF_420: return IMGFMT_YV12;
-+       case TH_PF_422: return IMGFMT_422P;
-+       case TH_PF_444: return IMGFMT_444P;
-     }
-     return 0;
- }
-@@ -64,7 +65,7 @@
-     theora_struct_t *context = sh->context;
-     switch(cmd) {
-     case VDCTRL_QUERY_FORMAT:
--        if (*(int*)arg == theora_pixelformat2imgfmt(context->inf.pixelformat))
-+        if (*(int*)arg == theora_pixelformat2imgfmt(context->ti.pixel_fmt))
- 	    return CONTROL_TRUE;
- 	return CONTROL_FALSE;
-     }
-@@ -88,8 +89,9 @@
-     if (!context)
-         goto err_out;
- 
--    theora_info_init(&context->inf);
--    theora_comment_init(&context->cc);
-+    th_info_init(&context->ti);
-+    th_comment_init(&context->tc);
-+    context->tsi = NULL;
- 
-     /* Read all header packets, pass them to theora_decode_header. */
-     for (i = 0; i < THEORA_NUM_HEADER_PACKETS; i++)
-@@ -109,7 +111,7 @@
-             op.b_o_s = 1;
-         }
- 
--        if ( (errorCode = theora_decode_header (&context->inf, &context->cc, &op)) )
-+        if ( (errorCode = th_decode_headerin (&context->ti, &context->tc, &context->tsi, &op)) < 0)
-         {
-             mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Broken Theora header; errorCode=%i!\n", errorCode);
-             goto err_out;
-@@ -117,23 +119,25 @@
-     }
- 
-     /* now init codec */
--    errorCode = theora_decode_init (&context->st, &context->inf);
--    if (errorCode)
-+    context->tctx = th_decode_alloc (&context->ti, context->tsi);
-+    if (!context->tctx)
-     {
--        mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Theora decode init failed: %i \n", errorCode);
-+        mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Theora decode init failed\n");
-         goto err_out;
-     }
-+    /* free memory used for decoder setup information */
-+    th_setup_free(context->tsi);
- 
--    if(sh->aspect==0.0 && context->inf.aspect_denominator!=0)
-+    if(sh->aspect==0.0 && context->ti.aspect_denominator!=0)
-     {
--       sh->aspect = ((double)context->inf.aspect_numerator * context->inf.width)/
--          ((double)context->inf.aspect_denominator * context->inf.height);
-+       sh->aspect = ((double)context->ti.aspect_numerator * context->ti.frame_width)/
-+          ((double)context->ti.aspect_denominator * context->ti.frame_height);
-     }
- 
-     mp_msg(MSGT_DECVIDEO,MSGL_V,"INFO: Theora video init ok!\n");
--    mp_msg(MSGT_DECVIDEO,MSGL_INFO,"Frame: %dx%d, Picture %dx%d, Offset [%d,%d]\n", context->inf.width, context->inf.height, context->inf.frame_width, context->inf.frame_height, context->inf.offset_x, context->inf.offset_y);
-+    mp_msg(MSGT_DECVIDEO,MSGL_INFO,"Frame: %dx%d, Picture %dx%d, Offset [%d,%d]\n", context->ti.frame_width, context->ti.frame_height, context->ti.pic_width, context->ti.pic_height, context->ti.pic_x, context->ti.pic_y);
- 
--    return mpcodecs_config_vo (sh,context->inf.width,context->inf.height,theora_pixelformat2imgfmt(context->inf.pixelformat));
-+    return mpcodecs_config_vo (sh,context->ti.frame_width,context->ti.frame_height,theora_pixelformat2imgfmt(context->ti.pixel_fmt));
- 
- err_out:
-     free(context);
-@@ -150,9 +154,9 @@
- 
-    if (context)
-    {
--      theora_info_clear(&context->inf);
--      theora_comment_clear(&context->cc);
--      theora_clear (&context->st);
-+      th_info_clear(&context->ti);
-+      th_comment_clear(&context->tc);
-+      th_decode_free (context->tctx);
-       free (context);
-    }
- }
-@@ -165,7 +169,7 @@
-    theora_struct_t *context = sh->context;
-    int errorCode = 0;
-    ogg_packet op;
--   yuv_buffer yuv;
-+   th_ycbcr_buffer ycbcrbuf;
-    mp_image_t* mpi;
- 
-    // no delayed frames
-@@ -177,31 +181,31 @@
-    op.packet = data;
-    op.granulepos = -1;
- 
--   errorCode = theora_decode_packetin (&context->st, &op);
--   if (errorCode)
-+   errorCode = th_decode_packetin (context->tctx, &op, NULL);
-+   if (errorCode < 0)
-    {
-       mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Theora decode packetin failed: %i \n",
- 	     errorCode);
-       return NULL;
-    }
- 
--   errorCode = theora_decode_YUVout (&context->st, &yuv);
--   if (errorCode)
-+   errorCode = th_decode_ycbcr_out (context->tctx, ycbcrbuf);
-+   if (errorCode < 0)
-    {
-       mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Theora decode YUVout failed: %i \n",
- 	     errorCode);
-       return NULL;
-    }
- 
--    mpi = mpcodecs_get_image(sh, MP_IMGTYPE_EXPORT, 0, yuv.y_width, yuv.y_height);
-+    mpi = mpcodecs_get_image(sh, MP_IMGTYPE_EXPORT, 0, ycbcrbuf[0].width, ycbcrbuf[0].height);
-     if(!mpi) return NULL;
- 
--    mpi->planes[0]=yuv.y;
--    mpi->stride[0]=yuv.y_stride;
--    mpi->planes[1]=yuv.u;
--    mpi->stride[1]=yuv.uv_stride;
--    mpi->planes[2]=yuv.v;
--    mpi->stride[2]=yuv.uv_stride;
-+    mpi->planes[0]=ycbcrbuf[0].data;
-+    mpi->stride[0]=ycbcrbuf[0].stride;
-+    mpi->planes[1]=ycbcrbuf[1].data;
-+    mpi->stride[1]=ycbcrbuf[1].stride;
-+    mpi->planes[2]=ycbcrbuf[2].data;
-+    mpi->stride[2]=ycbcrbuf[2].stride;
- 
-     return mpi;
- }
---- a/libmpdemux/demux_ogg.c
-+++ b/libmpdemux/demux_ogg.c
-@@ -49,21 +49,21 @@
- #endif
- 
- #ifdef CONFIG_OGGTHEORA
--#include <theora/theora.h>
--int _ilog (unsigned int); /* defined in many places in theora/lib/ */
-+#include <theora/theoradec.h>
- #endif
- 
- #define BLOCK_SIZE 4096
- 
- /* Theora decoder context : we won't be able to interpret granule positions
-- * without using theora_granule_time with the theora_state of the stream.
-+ * without using th_granule_time with the th_dec_ctx of the stream.
-  * This is duplicated in `vd_theora.c'; put this in a common header?
-  */
- #ifdef CONFIG_OGGTHEORA
- typedef struct theora_struct_st {
--    theora_state   st;
--    theora_comment cc;
--    theora_info    inf;
-+    th_setup_info *tsi;
-+    th_dec_ctx    *tctx;
-+    th_comment     tc;
-+    th_info        ti;
- } theora_struct_t;
- #endif
- 
-@@ -116,7 +116,7 @@
-     float   samplerate; /// granulpos 2 time
-     int64_t lastpos;
-     int32_t lastsize;
--    int     keyframe_frequency_force;
-+    int     keyframe_granule_shift;
- 
-     // Logical stream state
-     ogg_stream_state stream;
-@@ -299,11 +299,10 @@
-            have theora_state st, until all header packets were passed to the
-            decoder. */
-         if (!pack->bytes || !(*data&0x80)) {
--            int keyframe_granule_shift = _ilog(os->keyframe_frequency_force - 1);
--            int64_t iframemask = (1 << keyframe_granule_shift) - 1;
-+            int64_t iframemask = (1 << os->keyframe_granule_shift) - 1;
- 
-             if (pack->granulepos >= 0) {
--                os->lastpos  = pack->granulepos >> keyframe_granule_shift;
-+                os->lastpos  = pack->granulepos >> os->keyframe_granule_shift;
-                 os->lastpos += pack->granulepos & iframemask;
-                 *flags = (pack->granulepos & iframemask) == 0;
-             } else {
-@@ -892,14 +891,15 @@
- #ifdef CONFIG_OGGTHEORA
-         } else if (pack.bytes >= 7 && !strncmp (&pack.packet[1], "theora", 6)) {
-             int errorCode = 0;
--            theora_info inf;
--            theora_comment cc;
-+            th_info ti;
-+            th_comment tc;
-+            th_setup_info *tsi = NULL;
- 
--            theora_info_init (&inf);
--            theora_comment_init (&cc);
-+            th_info_init (&ti);
-+            th_comment_init (&tc);
- 
--            errorCode = theora_decode_header (&inf, &cc, &pack);
--            if (errorCode) {
-+            errorCode = th_decode_headerin(&ti, &tc, &tsi, &pack);
-+            if (errorCode < 0) {
-                 mp_msg(MSGT_DEMUX, MSGL_ERR,
-                        "Theora header parsing failed: %i \n", errorCode);
-             } else {
-@@ -908,30 +908,32 @@
-                 sh_v->bih = calloc(1, sizeof(*sh_v->bih));
-                 sh_v->bih->biSize        = sizeof(*sh_v->bih);
-                 sh_v->bih->biCompression = sh_v->format = FOURCC_THEORA;
--                sh_v->fps = ((double)inf.fps_numerator) / (double)inf.fps_denominator;
--                sh_v->frametime = ((double)inf.fps_denominator) / (double)inf.fps_numerator;
--                sh_v->disp_w = sh_v->bih->biWidth  = inf.frame_width;
--                sh_v->disp_h = sh_v->bih->biHeight = inf.frame_height;
-+                sh_v->fps = ((double)ti.fps_numerator) / (double)ti.fps_denominator;
-+                sh_v->frametime = ((double)ti.fps_denominator) / (double)ti.fps_numerator;
-+                sh_v->i_bps  = ti.target_bitrate / 8;
-+                sh_v->disp_w = sh_v->bih->biWidth  = ti.frame_width;
-+                sh_v->disp_h = sh_v->bih->biHeight = ti.frame_height;
-                 sh_v->bih->biBitCount  = 24;
-                 sh_v->bih->biPlanes    = 3;
-                 sh_v->bih->biSizeImage = ((sh_v->bih->biBitCount / 8) * sh_v->bih->biWidth * sh_v->bih->biHeight);
-                 ogg_d->subs[ogg_d->num_sub].samplerate               = sh_v->fps;
-                 ogg_d->subs[ogg_d->num_sub].theora                   = 1;
--                ogg_d->subs[ogg_d->num_sub].keyframe_frequency_force = inf.keyframe_frequency_force;
-+                ogg_d->subs[ogg_d->num_sub].keyframe_granule_shift   = ti.keyframe_granule_shift;
-                 ogg_d->subs[ogg_d->num_sub].id                       = n_video;
-                 n_video++;
-                 mp_msg(MSGT_DEMUX, MSGL_INFO,
-                        "[Ogg] stream %d: video (Theora v%d.%d.%d), -vid %d\n",
-                        ogg_d->num_sub,
--                       (int)inf.version_major,
--                       (int)inf.version_minor,
--                       (int)inf.version_subminor,
-+                       (int)ti.version_major,
-+                       (int)ti.version_minor,
-+                       (int)ti.version_subminor,
-                        n_video - 1);
-                 if (mp_msg_test(MSGT_HEADER, MSGL_V))
-                     print_video_header(sh_v->bih, MSGL_V);
-             }
--            theora_comment_clear(&cc);
--            theora_info_clear(&inf);
-+            th_comment_clear(&tc);
-+            th_info_clear(&ti);
-+            th_setup_free(tsi);
- #endif /* CONFIG_OGGTHEORA */
-         } else if (pack.bytes >= 4 && !strncmp (&pack.packet[0], "fLaC", 4)) {
-             sh_a = new_sh_audio_aid(demuxer, ogg_d->num_sub, n_audio, NULL);
diff --git a/gnu/packages/patches/nss-disable-long-b64-tests.patch b/gnu/packages/patches/nss-disable-long-b64-tests.patch
new file mode 100644
index 0000000000..612d94128d
--- /dev/null
+++ b/gnu/packages/patches/nss-disable-long-b64-tests.patch
@@ -0,0 +1,34 @@
+Disable long b64 tests, which consistently fail on armhf.
+This is based on an excerpt of the following upstream patch:
+
+  https://hg.mozilla.org/projects/nss/rev/00b2cc2b33c7
+
+(we exclude the part of the upstream patch that reverts
+an earlier failed attempt, and adapt the file names)
+
+diff --git a/gtests/util_gtest/util_b64_unittest.cc b/gtests/util_gtest/util_b64_unittest.cc
+--- a/nss/gtests/util_gtest/util_b64_unittest.cc
++++ b/nss/gtests/util_gtest/util_b64_unittest.cc
+@@ -63,17 +63,19 @@ TEST_F(B64EncodeDecodeTest, EncDecTest) 
+ 
+ TEST_F(B64EncodeDecodeTest, FakeDecTest) { EXPECT_TRUE(TestFakeDecode(100)); }
+ 
+ TEST_F(B64EncodeDecodeTest, FakeEncDecTest) {
+   EXPECT_TRUE(TestFakeEncode(100));
+ }
+ 
+ // These takes a while ...
+-TEST_F(B64EncodeDecodeTest, LongFakeDecTest1) {
++TEST_F(B64EncodeDecodeTest, DISABLED_LongFakeDecTest1) {
+   EXPECT_TRUE(TestFakeDecode(0x66666666));
+ }
+-TEST_F(B64EncodeDecodeTest, LongFakeEncDecTest1) { TestFakeEncode(0x3fffffff); }
+-TEST_F(B64EncodeDecodeTest, LongFakeEncDecTest2) {
++TEST_F(B64EncodeDecodeTest, DISABLED_LongFakeEncDecTest1) {
++  TestFakeEncode(0x3fffffff);
++}
++TEST_F(B64EncodeDecodeTest, DISABLED_LongFakeEncDecTest2) {
+   EXPECT_FALSE(TestFakeEncode(0x40000000));
+ }
+ 
+ }  // namespace nss_test
diff --git a/gnu/packages/patches/policycoreutils-make-sepolicy-use-python3.patch b/gnu/packages/patches/policycoreutils-make-sepolicy-use-python3.patch
new file mode 100644
index 0000000000..befe9fbb2a
--- /dev/null
+++ b/gnu/packages/patches/policycoreutils-make-sepolicy-use-python3.patch
@@ -0,0 +1,335 @@
+Downloaded from https://anonscm.debian.org/cgit/selinux/policycoreutils.git/plain/debian/patches/policycoreutils-Make-sepolicy-work-with-python3.patch
+
+From 2d7ca0b862a35196d562f59bd098df011fd7f0e6 Mon Sep 17 00:00:00 2001
+From: Laurent Bigonville <bigon@bigon.be>
+Date: Mon, 7 Nov 2016 10:51:08 +0100
+Subject: [PATCH] policycoreutils: Make sepolicy work with python3
+
+Add python3 support for sepolicy
+
+Signed-off-by: Laurent Bigonville <bigon@bigon.be>
+---
+ policycoreutils/sepolicy/selinux_client.py       |  6 ++--
+ policycoreutils/sepolicy/sepolicy.py             | 38 ++++++++++++------------
+ policycoreutils/sepolicy/sepolicy/__init__.py    | 16 ++++++----
+ policycoreutils/sepolicy/sepolicy/communicate.py |  4 +--
+ policycoreutils/sepolicy/sepolicy/generate.py    | 30 +++++++++----------
+ policycoreutils/sepolicy/sepolicy/interface.py   | 14 ++++++---
+ policycoreutils/sepolicy/sepolicy/manpage.py     |  7 +++--
+ 7 files changed, 65 insertions(+), 50 deletions(-)
+
+diff --git a/policycoreutils/sepolicy/selinux_client.py b/policycoreutils/sepolicy/selinux_client.py
+index 7f4a91c..dc29f28 100644
+--- a/sepolicy/selinux_client.py
++++ b/sepolicy/selinux_client.py
+@@ -39,6 +39,6 @@ if __name__ == "__main__":
+     try:
+         dbus_proxy = SELinuxDBus()
+         resp = dbus_proxy.customized()
+-        print convert_customization(resp)
+-    except dbus.DBusException, e:
+-        print e
++        print(convert_customization(resp))
++    except dbus.DBusException as e:
++        print(e)
+diff --git a/policycoreutils/sepolicy/sepolicy.py b/policycoreutils/sepolicy/sepolicy.py
+index 3e502a7..5bf9b52 100755
+--- a/sepolicy/sepolicy.py
++++ b/sepolicy/sepolicy.py
+@@ -262,7 +262,7 @@ def _print_net(src, protocol, perm):
+     if len(portdict) > 0:
+         bold_start = "\033[1m"
+         bold_end = "\033[0;0m"
+-        print "\n" + bold_start + "%s: %s %s" % (src, protocol, perm) + bold_end
++        print("\n" + bold_start + "%s: %s %s" % (src, protocol, perm) + bold_end)
+         port_strings = []
+         boolean_text = ""
+         for p in portdict:
+@@ -275,7 +275,7 @@ def _print_net(src, protocol, perm):
+                     port_strings.append("%s (%s)" % (", ".join(recs), t))
+         port_strings.sort(numcmp)
+         for p in port_strings:
+-            print "\t" + p
++            print("\t" + p)
+ 
+ 
+ def network(args):
+@@ -286,7 +286,7 @@ def network(args):
+             if i[0] not in all_ports:
+                 all_ports.append(i[0])
+         all_ports.sort()
+-        print "\n".join(all_ports)
++        print("\n".join(all_ports))
+ 
+     for port in args.port:
+         found = False
+@@ -297,18 +297,18 @@ def network(args):
+                 else:
+                     range = "%s-%s" % (i[0], i[1])
+                 found = True
+-                print "%d: %s %s %s" % (port, i[2], portrecsbynum[i][0], range)
++                print("%d: %s %s %s" % (port, i[2], portrecsbynum[i][0], range))
+         if not found:
+             if port < 500:
+-                print "Undefined reserved port type"
++                print("Undefined reserved port type")
+             else:
+-                print "Undefined port type"
++                print("Undefined port type")
+ 
+     for t in args.type:
+         if (t, 'tcp') in portrecs.keys():
+-            print "%s: tcp: %s" % (t, ",".join(portrecs[t, 'tcp']))
++            print("%s: tcp: %s" % (t, ",".join(portrecs[t, 'tcp'])))
+         if (t, 'udp') in portrecs.keys():
+-            print "%s: udp: %s" % (t, ",".join(portrecs[t, 'udp']))
++            print( "%s: udp: %s" % (t, ",".join(portrecs[t, 'udp'])))
+ 
+     for a in args.applications:
+         d = sepolicy.get_init_transtype(a)
+@@ -357,7 +357,7 @@ def manpage(args):
+ 
+     for domain in test_domains:
+         m = ManPage(domain, path, args.root, args.source_files, args.web)
+-        print m.get_man_page_path()
++        print(m.get_man_page_path())
+ 
+     if args.web:
+         HTMLManPages(manpage_roles, manpage_domains, path, args.os)
+@@ -418,7 +418,7 @@ def communicate(args):
+     out = list(set(writable) & set(readable))
+ 
+     for t in out:
+-        print t
++        print(t)
+ 
+ 
+ def gen_communicate_args(parser):
+@@ -445,7 +445,7 @@ def booleans(args):
+     args.booleans.sort()
+ 
+     for b in args.booleans:
+-        print "%s=_(\"%s\")" % (b, boolean_desc(b))
++        print("%s=_(\"%s\")" % (b, boolean_desc(b)))
+ 
+ 
+ def gen_booleans_args(parser):
+@@ -484,16 +484,16 @@ def print_interfaces(interfaces, args, append=""):
+     for i in interfaces:
+         if args.verbose:
+             try:
+-                print get_interface_format_text(i + append)
++                print(get_interface_format_text(i + append))
+             except KeyError:
+-                print i
++                print(i)
+         if args.compile:
+             try:
+                 interface_compile_test(i)
+             except KeyError:
+-                print i
++                print(i)
+         else:
+-            print i
++            print(i)
+ 
+ 
+ def interface(args):
+@@ -565,7 +565,7 @@ def generate(args):
+     if args.policytype in APPLICATIONS:
+         mypolicy.gen_writeable()
+         mypolicy.gen_symbols()
+-    print mypolicy.generate(args.path)
++    print(mypolicy.generate(args.path))
+ 
+ 
+ def gen_interface_args(parser):
+@@ -698,12 +698,12 @@ if __name__ == '__main__':
+         args = parser.parse_args(args=parser_args)
+         args.func(args)
+         sys.exit(0)
+-    except ValueError, e:
++    except ValueError as e:
+         sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
+         sys.exit(1)
+-    except IOError, e:
++    except IOError as e:
+         sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
+         sys.exit(1)
+     except KeyboardInterrupt:
+-        print "Out"
++        print("Out")
+         sys.exit(0)
+diff --git a/policycoreutils/sepolicy/sepolicy/__init__.py b/policycoreutils/sepolicy/sepolicy/__init__.py
+index 8fbd5b4..fee6438 100644
+--- a/sepolicy/sepolicy/__init__.py
++++ b/sepolicy/sepolicy/__init__.py
+@@ -695,7 +695,7 @@ def get_methods():
+     # List of per_role_template interfaces
+         ifs = interfaces.InterfaceSet()
+         ifs.from_file(fd)
+-        methods = ifs.interfaces.keys()
++        methods = list(ifs.interfaces.keys())
+         fd.close()
+     except:
+         sys.stderr.write("could not open interface info [%s]\n" % fn)
+@@ -752,7 +752,10 @@ def get_all_entrypoint_domains():
+ 
+ 
+ def gen_interfaces():
+-    import commands
++    try:
++        from commands import getstatusoutput
++    except ImportError:
++        from subprocess import getstatusoutput
+     ifile = defaults.interface_info()
+     headers = defaults.headers()
+     try:
+@@ -763,7 +766,7 @@ def gen_interfaces():
+ 
+     if os.getuid() != 0:
+         raise ValueError(_("You must regenerate interface info by running /usr/bin/sepolgen-ifgen"))
+-    print(commands.getstatusoutput("/usr/bin/sepolgen-ifgen")[1])
++    print(getstatusoutput("/usr/bin/sepolgen-ifgen")[1])
+ 
+ 
+ def gen_port_dict():
+@@ -1085,8 +1088,11 @@ def get_os_version():
+     os_version = ""
+     pkg_name = "selinux-policy"
+     try:
+-        import commands
+-        rc, output = commands.getstatusoutput("rpm -q '%s'" % pkg_name)
++        try:
++            from commands import getstatusoutput
++        except ImportError:
++            from subprocess import getstatusoutput
++        rc, output = getstatusoutput("rpm -q '%s'" % pkg_name)
+         if rc == 0:
+             os_version = output.split(".")[-2]
+     except:
+diff --git a/policycoreutils/sepolicy/sepolicy/communicate.py b/policycoreutils/sepolicy/sepolicy/communicate.py
+index b96c4b9..299316e 100755
+--- a/sepolicy/sepolicy/communicate.py
++++ b/sepolicy/sepolicy/communicate.py
+@@ -34,8 +34,8 @@ def usage(parser, msg):
+ 
+ def expand_attribute(attribute):
+     try:
+-        return sepolicy.info(sepolicy.ATTRIBUTE, attribute)[0]["types"]
+-    except RuntimeError:
++        return list(next(sepolicy.info(sepolicy.ATTRIBUTE, attribute))["types"])
++    except StopIteration:
+         return [attribute]
+ 
+ 
+diff --git a/policycoreutils/sepolicy/sepolicy/generate.py b/policycoreutils/sepolicy/sepolicy/generate.py
+index 65b33b6..5696110 100644
+--- a/sepolicy/sepolicy/generate.py
++++ b/sepolicy/sepolicy/generate.py
+@@ -31,21 +31,21 @@ import time
+ import types
+ import platform
+ 
+-from templates import executable
+-from templates import boolean
+-from templates import etc_rw
+-from templates import unit_file
+-from templates import var_cache
+-from templates import var_spool
+-from templates import var_lib
+-from templates import var_log
+-from templates import var_run
+-from templates import tmp
+-from templates import rw
+-from templates import network
+-from templates import script
+-from templates import spec
+-from templates import user
++from .templates import executable
++from .templates import boolean
++from .templates import etc_rw
++from .templates import unit_file
++from .templates import var_cache
++from .templates import var_spool
++from .templates import var_lib
++from .templates import var_log
++from .templates import var_run
++from .templates import tmp
++from .templates import rw
++from .templates import network
++from .templates import script
++from .templates import spec
++from .templates import user
+ import sepolgen.interfaces as interfaces
+ import sepolgen.defaults as defaults
+ 
+diff --git a/policycoreutils/sepolicy/sepolicy/interface.py b/policycoreutils/sepolicy/sepolicy/interface.py
+index c2cb971..8956f39 100644
+--- a/sepolicy/sepolicy/interface.py
++++ b/sepolicy/sepolicy/interface.py
+@@ -192,10 +192,13 @@ def generate_compile_te(interface, idict, name="compiletest"):
+ def get_xml_file(if_file):
+     """ Returns xml format of interfaces for given .if policy file"""
+     import os
+-    import commands
++    try:
++            from commands import getstatusoutput
++    except ImportError:
++            from subprocess import getstatusoutput
+     basedir = os.path.dirname(if_file) + "/"
+     filename = os.path.basename(if_file).split(".")[0]
+-    rc, output = commands.getstatusoutput("python /usr/share/selinux/devel/include/support/segenxml.py -w -m %s" % basedir + filename)
++    rc, output = getstatusoutput("python /usr/share/selinux/devel/include/support/segenxml.py -w -m %s" % basedir + filename)
+     if rc != 0:
+         sys.stderr.write("\n Could not proceed selected interface file.\n")
+         sys.stderr.write("\n%s" % output)
+@@ -208,7 +211,10 @@ def interface_compile_test(interface, path="/usr/share/selinux/devel/policy.xml"
+     exclude_interfaces = ["userdom", "kernel", "corenet", "files", "dev"]
+     exclude_interface_type = ["template"]
+ 
+-    import commands
++    try:
++            from commands import getstatusoutput
++    except ImportError:
++            from subprocess import getstatusoutput
+     import os
+     policy_files = {'pp': "compiletest.pp", 'te': "compiletest.te", 'fc': "compiletest.fc", 'if': "compiletest.if"}
+     idict = get_interface_dict(path)
+@@ -219,7 +225,7 @@ def interface_compile_test(interface, path="/usr/share/selinux/devel/policy.xml"
+             fd = open(policy_files['te'], "w")
+             fd.write(generate_compile_te(interface, idict))
+             fd.close()
+-            rc, output = commands.getstatusoutput("make -f /usr/share/selinux/devel/Makefile %s" % policy_files['pp'])
++            rc, output = getstatusoutput("make -f /usr/share/selinux/devel/Makefile %s" % policy_files['pp'])
+             if rc != 0:
+                 sys.stderr.write(output)
+                 sys.stderr.write(_("\nCompile test for %s failed.\n") % interface)
+diff --git a/policycoreutils/sepolicy/sepolicy/manpage.py b/policycoreutils/sepolicy/sepolicy/manpage.py
+index 7365f93..773a9ab 100755
+--- a/sepolicy/sepolicy/manpage.py
++++ b/sepolicy/sepolicy/manpage.py
+@@ -27,7 +27,6 @@ __all__ = ['ManPage', 'HTMLManPages', 'manpage_domains', 'manpage_roles', 'gen_d
+ import string
+ import selinux
+ import sepolicy
+-import commands
+ import os
+ import time
+ 
+@@ -162,7 +161,11 @@ def get_alphabet_manpages(manpage_list):
+ 
+ 
+ def convert_manpage_to_html(html_manpage, manpage):
+-    rc, output = commands.getstatusoutput("/usr/bin/groff -man -Thtml %s 2>/dev/null" % manpage)
++    try:
++            from commands import getstatusoutput
++    except ImportError:
++            from subprocess import getstatusoutput
++    rc, output = getstatusoutput("/usr/bin/groff -man -Thtml %s 2>/dev/null" % manpage)
+     if rc == 0:
+         print(html_manpage, "has been created")
+         fd = open(html_manpage, 'w')
+-- 
+2.10.2
+
diff --git a/gnu/packages/patches/portaudio-audacity-compat.patch b/gnu/packages/patches/portaudio-audacity-compat.patch
index 9f239ada35..513d08bcea 100644
--- a/gnu/packages/patches/portaudio-audacity-compat.patch
+++ b/gnu/packages/patches/portaudio-audacity-compat.patch
@@ -7,27 +7,27 @@ See <http://music.columbia.edu/pipermail/portaudio/2015-March/016611.html>.
 --- a/include/pa_win_ds.h
 +++ b/include/pa_win_ds.h
 @@ -89,6 +89,21 @@
- 

- }PaWinDirectSoundStreamInfo;

- 

-+/** Retrieve the GUID of the input device.

-+

-+ @param stream The stream to query.

-+

-+ @return A pointer to the GUID, or NULL if none.

-+*/

-+LPGUID PaWinDS_GetStreamInputGUID( PaStream* s );

-+

-+/** Retrieve the GUID of the output device.

-+

-+ @param stream The stream to query.

-+

-+ @return A pointer to the GUID, or NULL if none.

-+*/

-+LPGUID PaWinDS_GetStreamOutputGUID( PaStream* s );

- 

- 

- #ifdef __cplusplus

+
+ }PaWinDirectSoundStreamInfo;
+
++/** Retrieve the GUID of the input device.
++
++ @param stream The stream to query.
++
++ @return A pointer to the GUID, or NULL if none.
++*/
++LPGUID PaWinDS_GetStreamInputGUID( PaStream* s );
++
++/** Retrieve the GUID of the output device.
++
++ @param stream The stream to query.
++
++ @return A pointer to the GUID, or NULL if none.
++*/
++LPGUID PaWinDS_GetStreamOutputGUID( PaStream* s );
+
+
+ #ifdef __cplusplus
 --- a/include/portaudio.h
 +++ b/include/portaudio.h
 @@ -1146,6 +1146,15 @@
@@ -224,15 +224,15 @@ See <http://music.columbia.edu/pipermail/portaudio/2015-March/016611.html>.
 --- a/src/hostapi/coreaudio/pa_mac_core_blocking.c
 +++ b/src/hostapi/coreaudio/pa_mac_core_blocking.c
 @@ -66,6 +66,9 @@
- #ifdef MOSX_USE_NON_ATOMIC_FLAG_BITS

- # define OSAtomicOr32( a, b ) ( (*(b)) |= (a) )

- # define OSAtomicAnd32( a, b ) ( (*(b)) &= (a) )

-+#elif MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_3

-+# define OSAtomicOr32( a, b ) BitOrAtomic( a, (UInt32 *) b )

-+# define OSAtomicAnd32( a, b ) BitAndAtomic( a, (UInt32 *) b )

- #else

- # include <libkern/OSAtomic.h>

- #endif

+ #ifdef MOSX_USE_NON_ATOMIC_FLAG_BITS
+ # define OSAtomicOr32( a, b ) ( (*(b)) |= (a) )
+ # define OSAtomicAnd32( a, b ) ( (*(b)) &= (a) )
++#elif MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_3
++# define OSAtomicOr32( a, b ) BitOrAtomic( a, (UInt32 *) b )
++# define OSAtomicAnd32( a, b ) BitAndAtomic( a, (UInt32 *) b )
+ #else
+ # include <libkern/OSAtomic.h>
+ #endif
 --- a/src/hostapi/alsa/pa_linux_alsa.c
 +++ b/src/hostapi/alsa/pa_linux_alsa.c
 @@ -611,6 +611,7 @@
diff --git a/gnu/packages/patches/python-pyopenssl-skip-network-test.patch b/gnu/packages/patches/python-pyopenssl-skip-network-test.patch
index a24eaf69a0..1ac7324c8b 100644
--- a/gnu/packages/patches/python-pyopenssl-skip-network-test.patch
+++ b/gnu/packages/patches/python-pyopenssl-skip-network-test.patch
@@ -7,20 +7,14 @@ diff --git a/tests/test_ssl.py b/tests/test_ssl.py
 index ee849fd..60048b8 100644
 --- a/tests/test_ssl.py
 +++ b/tests/test_ssl.py
-@@ -1180,40 +1180,6 @@ class ContextTests(TestCase, _LoopbackMixin):
-             TypeError, context.load_verify_locations, None, None, None
-         )
- 
--    @pytest.mark.skipif(
--        platform == "win32",
--        reason="set_default_verify_paths appears not to work on Windows.  "
--        "See LP#404343 and LP#404344."
--    )
+@@ -1113,33 +1113,6 @@ class TestContext(object):
+         reason="set_default_verify_paths appears not to work on Windows.  "
+         "See LP#404343 and LP#404344."
+     )
 -    def test_set_default_verify_paths(self):
 -        """
--        :py:obj:`Context.set_default_verify_paths` causes the
--        platform-specific CA certificate locations to be used for
--        verification purposes.
+-        `Context.set_default_verify_paths` causes the platform-specific CA
+-        certificate locations to be used for verification purposes.
 -        """
 -        # Testing this requires a server with a certificate signed by one
 -        # of the CAs in the platform CA location.  Getting one of those
@@ -43,8 +37,7 @@ index ee849fd..60048b8 100644
 -        clientSSL.set_connect_state()
 -        clientSSL.do_handshake()
 -        clientSSL.send(b"GET / HTTP/1.0\r\n\r\n")
--        self.assertTrue(clientSSL.recv(1024))
--
-     def test_set_default_verify_paths_signature(self):
+-        assert clientSSL.recv(1024)
+ 
+     def test_add_extra_chain_cert_invalid_cert(self):
          """
-         :py:obj:`Context.set_default_verify_paths` takes no arguments and
diff --git a/gnu/packages/patches/qemu-CVE-2016-10155.patch b/gnu/packages/patches/qemu-CVE-2016-10155.patch
deleted file mode 100644
index 825edaa815..0000000000
--- a/gnu/packages/patches/qemu-CVE-2016-10155.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From eb7a20a3616085d46aa6b4b4224e15587ec67e6e Mon Sep 17 00:00:00 2001
-From: Li Qiang <liqiang6-s@360.cn>
-Date: Mon, 28 Nov 2016 17:49:04 -0800
-Subject: [PATCH] watchdog: 6300esb: add exit function
-
-When the Intel 6300ESB watchdog is hot unplug. The timer allocated
-in realize isn't freed thus leaking memory leak. This patch avoid
-this through adding the exit function.
-
-http://git.qemu.org/?p=qemu.git;a=patch;h=eb7a20a3616085d46aa6b4b4224e15587ec67e6e
-this patch is from qemu-git.
-
-Signed-off-by: Li Qiang <liqiang6-s@360.cn>
-Message-Id: <583cde9c.3223ed0a.7f0c2.886e@mx.google.com>
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- hw/watchdog/wdt_i6300esb.c |    9 +++++++++
- 1 files changed, 9 insertions(+), 0 deletions(-)
-
-diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c
-index a83d951..49b3cd1 100644
---- a/hw/watchdog/wdt_i6300esb.c
-+++ b/hw/watchdog/wdt_i6300esb.c
-@@ -428,6 +428,14 @@ static void i6300esb_realize(PCIDevice *dev, Error **errp)
-     /* qemu_register_coalesced_mmio (addr, 0x10); ? */
- }
- 
-+static void i6300esb_exit(PCIDevice *dev)
-+{
-+    I6300State *d = WATCHDOG_I6300ESB_DEVICE(dev);
-+
-+    timer_del(d->timer);
-+    timer_free(d->timer);
-+}
-+
- static WatchdogTimerModel model = {
-     .wdt_name = "i6300esb",
-     .wdt_description = "Intel 6300ESB",
-@@ -441,6 +449,7 @@ static void i6300esb_class_init(ObjectClass *klass, void *data)
-     k->config_read = i6300esb_config_read;
-     k->config_write = i6300esb_config_write;
-     k->realize = i6300esb_realize;
-+    k->exit = i6300esb_exit;
-     k->vendor_id = PCI_VENDOR_ID_INTEL;
-     k->device_id = PCI_DEVICE_ID_INTEL_ESB_9;
-     k->class_id = PCI_CLASS_SYSTEM_OTHER;
--- 
-1.7.0.4
-
diff --git a/gnu/packages/patches/qemu-CVE-2017-5525.patch b/gnu/packages/patches/qemu-CVE-2017-5525.patch
deleted file mode 100644
index d0c0c82a4a..0000000000
--- a/gnu/packages/patches/qemu-CVE-2017-5525.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 12351a91da97b414eec8cdb09f1d9f41e535a401 Mon Sep 17 00:00:00 2001
-From: Li Qiang <liqiang6-s@360.cn>
-Date: Wed, 14 Dec 2016 18:30:21 -0800
-Subject: [PATCH] audio: ac97: add exit function
-MIME-Version: 1.0
-Content-Type: text/plain; charset=utf8
-Content-Transfer-Encoding: 8bit
-
-http://git.qemu.org/?p=qemu.git;a=patch;h=12351a91da97b414eec8cdb09f1d9f41e535a401
-this patch is from qemu-git
-
-Currently the ac97 device emulation doesn't have a exit function,
-hot unplug this device will leak some memory. Add a exit function to
-avoid this.
-
-Signed-off-by: Li Qiang <liqiang6-s@360.cn>
-Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
-Message-id: 58520052.4825ed0a.27a71.6cae@mx.google.com
-Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
----
- hw/audio/ac97.c |   11 +++++++++++
- 1 files changed, 11 insertions(+), 0 deletions(-)
-
-diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c
-index cbd959e..c306575 100644
---- a/hw/audio/ac97.c
-+++ b/hw/audio/ac97.c
-@@ -1387,6 +1387,16 @@ static void ac97_realize(PCIDevice *dev, Error **errp)
-     ac97_on_reset (&s->dev.qdev);
- }
- 
-+static void ac97_exit(PCIDevice *dev)
-+{
-+    AC97LinkState *s = DO_UPCAST(AC97LinkState, dev, dev);
-+
-+    AUD_close_in(&s->card, s->voice_pi);
-+    AUD_close_out(&s->card, s->voice_po);
-+    AUD_close_in(&s->card, s->voice_mc);
-+    AUD_remove_card(&s->card);
-+}
-+
- static int ac97_init (PCIBus *bus)
- {
-     pci_create_simple (bus, -1, "AC97");
-@@ -1404,6 +1414,7 @@ static void ac97_class_init (ObjectClass *klass, void *data)
-     PCIDeviceClass *k = PCI_DEVICE_CLASS (klass);
- 
-     k->realize = ac97_realize;
-+    k->exit = ac97_exit;
-     k->vendor_id = PCI_VENDOR_ID_INTEL;
-     k->device_id = PCI_DEVICE_ID_INTEL_82801AA_5;
-     k->revision = 0x01;
--- 
-1.7.0.4
-
diff --git a/gnu/packages/patches/qemu-CVE-2017-5526.patch b/gnu/packages/patches/qemu-CVE-2017-5526.patch
deleted file mode 100644
index 5a6d796458..0000000000
--- a/gnu/packages/patches/qemu-CVE-2017-5526.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 069eb7b2b8fc47c7cb52e5a4af23ea98d939e3da Mon Sep 17 00:00:00 2001
-From: Li Qiang <liqiang6-s@360.cn>
-Date: Wed, 14 Dec 2016 18:32:22 -0800
-Subject: [PATCH] audio: es1370: add exit function
-MIME-Version: 1.0
-Content-Type: text/plain; charset=utf8
-Content-Transfer-Encoding: 8bit
-
-http://git.qemu.org/?p=qemu.git;a=patch;h=069eb7b2b8fc47c7cb52e5a4af23ea98d939e3da
-this patch is from qemu-git.
-
-Currently the es1370 device emulation doesn't have a exit function,
-hot unplug this device will leak some memory. Add a exit function to
-avoid this.
-
-Signed-off-by: Li Qiang <liqiang6-s@360.cn>
-Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
-Message-id: 585200c9.a968ca0a.1ab80.4c98@mx.google.com
-Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
----
- hw/audio/es1370.c |   14 ++++++++++++++
- 1 files changed, 14 insertions(+), 0 deletions(-)
-
-diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c
-index 8449b5f..883ec69 100644
---- a/hw/audio/es1370.c
-+++ b/hw/audio/es1370.c
-@@ -1041,6 +1041,19 @@ static void es1370_realize(PCIDevice *dev, Error **errp)
-     es1370_reset (s);
- }
- 
-+static void es1370_exit(PCIDevice *dev)
-+{
-+    ES1370State *s = ES1370(dev);
-+    int i;
-+
-+    for (i = 0; i < 2; ++i) {
-+        AUD_close_out(&s->card, s->dac_voice[i]);
-+    }
-+
-+    AUD_close_in(&s->card, s->adc_voice);
-+    AUD_remove_card(&s->card);
-+}
-+
- static int es1370_init (PCIBus *bus)
- {
-     pci_create_simple (bus, -1, TYPE_ES1370);
-@@ -1053,6 +1066,7 @@ static void es1370_class_init (ObjectClass *klass, void *data)
-     PCIDeviceClass *k = PCI_DEVICE_CLASS (klass);
- 
-     k->realize = es1370_realize;
-+    k->exit = es1370_exit;
-     k->vendor_id = PCI_VENDOR_ID_ENSONIQ;
-     k->device_id = PCI_DEVICE_ID_ENSONIQ_ES1370;
-     k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
--- 
-1.7.0.4
-
diff --git a/gnu/packages/patches/qemu-CVE-2017-5552.patch b/gnu/packages/patches/qemu-CVE-2017-5552.patch
deleted file mode 100644
index 50911f4f36..0000000000
--- a/gnu/packages/patches/qemu-CVE-2017-5552.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 33243031dad02d161225ba99d782616da133f689 Mon Sep 17 00:00:00 2001
-From: Li Qiang <liq3ea@gmail.com>
-Date: Thu, 29 Dec 2016 03:11:26 -0500
-Subject: [PATCH] virtio-gpu-3d: fix memory leak in resource attach backing
-MIME-Version: 1.0
-Content-Type: text/plain; charset=utf8
-Content-Transfer-Encoding: 8bit
-
-If the virgl_renderer_resource_attach_iov function fails the
-'res_iovs' will be leaked. Add check of the return value to
-free the 'res_iovs' when failing.
-
-http://git.qemu.org/?p=qemu.git;a=patch;h=33243031dad02d161225ba99d782616da133f689
-this patch is from qemu-git.
-
-Signed-off-by: Li Qiang <liq3ea@gmail.com>
-Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
-Message-id: 1482999086-59795-1-git-send-email-liq3ea@gmail.com
-Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
----
- hw/display/virtio-gpu-3d.c |    7 +++++--
- 1 files changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/hw/display/virtio-gpu-3d.c b/hw/display/virtio-gpu-3d.c
-index e29f099..b13ced3 100644
---- a/hw/display/virtio-gpu-3d.c
-+++ b/hw/display/virtio-gpu-3d.c
-@@ -291,8 +291,11 @@ static void virgl_resource_attach_backing(VirtIOGPU *g,
-         return;
-     }
- 
--    virgl_renderer_resource_attach_iov(att_rb.resource_id,
--                                       res_iovs, att_rb.nr_entries);
-+    ret = virgl_renderer_resource_attach_iov(att_rb.resource_id,
-+                                             res_iovs, att_rb.nr_entries);
-+
-+    if (ret != 0)
-+        virtio_gpu_cleanup_mapping_iov(res_iovs, att_rb.nr_entries);
- }
- 
- static void virgl_resource_detach_backing(VirtIOGPU *g,
--- 
-1.7.0.4
-
diff --git a/gnu/packages/patches/qemu-CVE-2017-5578.patch b/gnu/packages/patches/qemu-CVE-2017-5578.patch
deleted file mode 100644
index 05655bcd98..0000000000
--- a/gnu/packages/patches/qemu-CVE-2017-5578.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-http://git.qemu.org/?p=qemu.git;a=patch;h=204f01b30975923c64006f8067f0937b91eea68b
-this patch is from qemu-git.
-
-
-From 204f01b30975923c64006f8067f0937b91eea68b Mon Sep 17 00:00:00 2001
-From: Li Qiang <liq3ea@gmail.com>
-Date: Thu, 29 Dec 2016 04:28:41 -0500
-Subject: [PATCH] virtio-gpu: fix memory leak in resource attach backing
-
-In the resource attach backing function, everytime it will
-allocate 'res->iov' thus can leading a memory leak. This
-patch avoid this.
-
-Signed-off-by: Li Qiang <liq3ea@gmail.com>
-Message-id: 1483003721-65360-1-git-send-email-liq3ea@gmail.com
-Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
----
- hw/display/virtio-gpu.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
-index 6a26258cac..ca88cf478d 100644
---- a/hw/display/virtio-gpu.c
-+++ b/hw/display/virtio-gpu.c
-@@ -714,6 +714,11 @@ virtio_gpu_resource_attach_backing(VirtIOGPU *g,
-         return;
-     }
- 
-+    if (res->iov) {
-+        cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
-+        return;
-+    }
-+
-     ret = virtio_gpu_create_mapping_iov(&ab, cmd, &res->addrs, &res->iov);
-     if (ret != 0) {
-         cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
--- 
-2.11.0
-
diff --git a/gnu/packages/patches/qemu-CVE-2017-5579.patch b/gnu/packages/patches/qemu-CVE-2017-5579.patch
deleted file mode 100644
index 7630012d54..0000000000
--- a/gnu/packages/patches/qemu-CVE-2017-5579.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-http://git.qemu.org/?p=qemu.git;a=patch;h=8409dc884a201bf74b30a9d232b6bbdd00cb7e2b
-this patch is from qemu-git.
-
-
-From 8409dc884a201bf74b30a9d232b6bbdd00cb7e2b Mon Sep 17 00:00:00 2001
-From: Li Qiang <liqiang6-s@360.cn>
-Date: Wed, 4 Jan 2017 00:43:16 -0800
-Subject: [PATCH] serial: fix memory leak in serial exit
-
-The serial_exit_core function doesn't free some resources.
-This can lead memory leak when hotplug and unplug. This
-patch avoid this.
-
-Signed-off-by: Li Qiang <liqiang6-s@360.cn>
-Message-Id: <586cb5ab.f31d9d0a.38ac3.acf2@mx.google.com>
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- hw/char/serial.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/hw/char/serial.c b/hw/char/serial.c
-index ffbacd8227..67b18eda12 100644
---- a/hw/char/serial.c
-+++ b/hw/char/serial.c
-@@ -906,6 +906,16 @@ void serial_realize_core(SerialState *s, Error **errp)
- void serial_exit_core(SerialState *s)
- {
-     qemu_chr_fe_deinit(&s->chr);
-+
-+    timer_del(s->modem_status_poll);
-+    timer_free(s->modem_status_poll);
-+
-+    timer_del(s->fifo_timeout_timer);
-+    timer_free(s->fifo_timeout_timer);
-+
-+    fifo8_destroy(&s->recv_fifo);
-+    fifo8_destroy(&s->xmit_fifo);
-+
-     qemu_unregister_reset(serial_reset, s);
- }
- 
--- 
-2.11.0
-
diff --git a/gnu/packages/patches/qemu-CVE-2017-5856.patch b/gnu/packages/patches/qemu-CVE-2017-5856.patch
deleted file mode 100644
index bee0824c0a..0000000000
--- a/gnu/packages/patches/qemu-CVE-2017-5856.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-http://git.qemu.org/?p=qemu.git;a=patch;h=765a707000e838c30b18d712fe6cb3dd8e0435f3
-this patch is from qemu-git.
-
-
-From 765a707000e838c30b18d712fe6cb3dd8e0435f3 Mon Sep 17 00:00:00 2001
-From: Paolo Bonzini <pbonzini@redhat.com>
-Date: Mon, 2 Jan 2017 11:03:33 +0100
-Subject: [PATCH] megasas: fix guest-triggered memory leak
-
-If the guest sets the sglist size to a value >=2GB, megasas_handle_dcmd
-will return MFI_STAT_MEMORY_NOT_AVAILABLE without freeing the memory.
-Avoid this by returning only the status from map_dcmd, and loading
-cmd->iov_size in the caller.
-
-Reported-by: Li Qiang <liqiang6-s@360.cn>
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- hw/scsi/megasas.c |   11 ++++++-----
- 1 files changed, 6 insertions(+), 5 deletions(-)
-
-diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
-index 67fc1e7..6233865 100644
---- a/hw/scsi/megasas.c
-+++ b/hw/scsi/megasas.c
-@@ -683,14 +683,14 @@ static int megasas_map_dcmd(MegasasState *s, MegasasCmd *cmd)
-         trace_megasas_dcmd_invalid_sge(cmd->index,
-                                        cmd->frame->header.sge_count);
-         cmd->iov_size = 0;
--        return -1;
-+        return -EINVAL;
-     }
-     iov_pa = megasas_sgl_get_addr(cmd, &cmd->frame->dcmd.sgl);
-     iov_size = megasas_sgl_get_len(cmd, &cmd->frame->dcmd.sgl);
-     pci_dma_sglist_init(&cmd->qsg, PCI_DEVICE(s), 1);
-     qemu_sglist_add(&cmd->qsg, iov_pa, iov_size);
-     cmd->iov_size = iov_size;
--    return cmd->iov_size;
-+    return 0;
- }
- 
- static void megasas_finish_dcmd(MegasasCmd *cmd, uint32_t iov_size)
-@@ -1559,19 +1559,20 @@ static const struct dcmd_cmd_tbl_t {
- 
- static int megasas_handle_dcmd(MegasasState *s, MegasasCmd *cmd)
- {
--    int opcode, len;
-+    int opcode;
-     int retval = 0;
-+    size_t len;
-     const struct dcmd_cmd_tbl_t *cmdptr = dcmd_cmd_tbl;
- 
-     opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
-     trace_megasas_handle_dcmd(cmd->index, opcode);
--    len = megasas_map_dcmd(s, cmd);
--    if (len < 0) {
-+    if (megasas_map_dcmd(s, cmd) < 0) {
-         return MFI_STAT_MEMORY_NOT_AVAILABLE;
-     }
-     while (cmdptr->opcode != -1 && cmdptr->opcode != opcode) {
-         cmdptr++;
-     }
-+    len = cmd->iov_size;
-     if (cmdptr->opcode == -1) {
-         trace_megasas_dcmd_unhandled(cmd->index, opcode, len);
-         retval = megasas_dcmd_dummy(s, cmd);
--- 
-1.7.0.4
-
diff --git a/gnu/packages/patches/qemu-CVE-2017-5898.patch b/gnu/packages/patches/qemu-CVE-2017-5898.patch
deleted file mode 100644
index 5a94bb1ae4..0000000000
--- a/gnu/packages/patches/qemu-CVE-2017-5898.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-Fix CVE-2017-5898 (integer overflow in emulated_apdu_from_guest):
-
-http://seclists.org/oss-sec/2017/q1/328
-https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5898
-
-Patch copied from upstream source repository:
-
-http://git.qemu-project.org/?p=qemu.git;a=commitdiff;h=c7dfbf322595ded4e70b626bf83158a9f3807c6a
-
-From c7dfbf322595ded4e70b626bf83158a9f3807c6a Mon Sep 17 00:00:00 2001
-From: Prasad J Pandit <pjp@fedoraproject.org>
-Date: Fri, 3 Feb 2017 00:52:28 +0530
-Subject: [PATCH] usb: ccid: check ccid apdu length
-
-CCID device emulator uses Application Protocol Data Units(APDU)
-to exchange command and responses to and from the host.
-The length in these units couldn't be greater than 65536. Add
-check to ensure the same. It'd also avoid potential integer
-overflow in emulated_apdu_from_guest.
-
-Reported-by: Li Qiang <liqiang6-s@360.cn>
-Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
-Message-id: 20170202192228.10847-1-ppandit@redhat.com
-Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
----
- hw/usb/dev-smartcard-reader.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
-index 89e11b68c4..1325ea1659 100644
---- a/hw/usb/dev-smartcard-reader.c
-+++ b/hw/usb/dev-smartcard-reader.c
-@@ -967,7 +967,7 @@ static void ccid_on_apdu_from_guest(USBCCIDState *s, CCID_XferBlock *recv)
-     DPRINTF(s, 1, "%s: seq %d, len %d\n", __func__,
-                 recv->hdr.bSeq, len);
-     ccid_add_pending_answer(s, (CCID_Header *)recv);
--    if (s->card) {
-+    if (s->card && len <= BULK_OUT_DATA_SIZE) {
-         ccid_card_apdu_from_guest(s->card, recv->abData, len);
-     } else {
-         DPRINTF(s, D_WARN, "warning: discarded apdu\n");
--- 
-2.11.1
-
diff --git a/gnu/packages/patches/soprano-find-clucene.patch b/gnu/packages/patches/soprano-find-clucene.patch
deleted file mode 100644
index cc2707853a..0000000000
--- a/gnu/packages/patches/soprano-find-clucene.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-Search for clucene include file in the clucene include directory.
-
-diff -u -r soprano-2.9.4.orig/cmake/modules/FindCLucene.cmake soprano-2.9.4/cmake/modules/FindCLucene.cmake
---- soprano-2.9.4.orig/cmake/modules/FindCLucene.cmake	2013-10-09 19:22:28.000000000 +0200
-+++ soprano-2.9.4/cmake/modules/FindCLucene.cmake	2014-04-28 20:08:11.000000000 +0200
-@@ -77,7 +77,8 @@
- 
- get_filename_component(TRIAL_LIBRARY_DIR ${CLUCENE_LIBRARY} PATH)
- find_path(CLUCENE_LIBRARY_DIR
--  NAMES CLucene/clucene-config.h PATHS ${TRIAL_LIBRARY_DIR} ${TRIAL_LIBRARY_PATHS} ${TRIAL_INCLUDE_PATHS} NO_DEFAULT_PATH)
-+  NAMES CLucene/clucene-config.h PATHS ${TRIAL_LIBRARY_DIR} ${TRIAL_LIBRARY_PATHS} ${TRIAL_INCLUDE_PATHS} ${CLUCENE_INCLUDE_DIR} NO_DEFAULT_PATH)
-+message (STATUS "XXX ${CLUCENE_LIBRARY_DIR}")
- if(CLUCENE_LIBRARY_DIR)
-   message(STATUS "Found CLucene library dir: ${CLUCENE_LIBRARY_DIR}")
-   file(READ ${CLUCENE_LIBRARY_DIR}/CLucene/clucene-config.h CLCONTENT)
diff --git a/gnu/packages/patches/util-linux-CVE-2017-2616.patch b/gnu/packages/patches/util-linux-CVE-2017-2616.patch
deleted file mode 100644
index 2c82fb06d2..0000000000
--- a/gnu/packages/patches/util-linux-CVE-2017-2616.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-Fix CVE-2017-2616:
-
-https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-2616
-http://seclists.org/oss-sec/2017/q1/474
-
-Patch copied from upstream source repository:
-
-https://git.kernel.org/cgit/utils/util-linux/util-linux.git/commit/?id=dffab154d29a288aa171ff50263ecc8f2e14a891
-
-From b018571132cb8c9fece3d75ed240cc74cdb5f0f7 Mon Sep 17 00:00:00 2001
-From: Karel Zak <kzak@redhat.com>
-Date: Wed, 1 Feb 2017 11:58:09 +0100
-Subject: [PATCH] su: properly clear child PID
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Reported-by: Tobias Stöckmann <tobias@stoeckmann.org>
-Signed-off-by: Karel Zak <kzak@redhat.com>
----
- login-utils/su-common.c | 14 ++++++++++----
- 1 file changed, 10 insertions(+), 4 deletions(-)
-
-diff --git a/login-utils/su-common.c b/login-utils/su-common.c
-index 0ea4e40bd..b1720f037 100644
---- a/login-utils/su-common.c
-+++ b/login-utils/su-common.c
-@@ -376,6 +376,9 @@ create_watching_parent (void)
-             }
-           else
-             status = WEXITSTATUS (status);
-+
-+	  /* child is gone, don't use the PID anymore */
-+	  child = (pid_t) -1;
-         }
-       else if (caught_signal)
-         status = caught_signal + 128;
-@@ -385,7 +388,7 @@ create_watching_parent (void)
-   else
-     status = 1;
- 
--  if (caught_signal)
-+  if (caught_signal && child != (pid_t)-1)
-     {
-       fprintf (stderr, _("\nSession terminated, killing shell..."));
-       kill (child, SIGTERM);
-@@ -395,9 +398,12 @@ create_watching_parent (void)
- 
-   if (caught_signal)
-     {
--      sleep (2);
--      kill (child, SIGKILL);
--      fprintf (stderr, _(" ...killed.\n"));
-+      if (child != (pid_t)-1)
-+	{
-+	  sleep (2);
-+	  kill (child, SIGKILL);
-+	  fprintf (stderr, _(" ...killed.\n"));
-+	}
- 
-       /* Let's terminate itself with the received signal.
-        *
--- 
-2.11.1
-
diff --git a/gnu/packages/patches/xf86-video-intel-compat-api.patch b/gnu/packages/patches/xf86-video-intel-compat-api.patch
deleted file mode 100644
index 786de5c45d..0000000000
--- a/gnu/packages/patches/xf86-video-intel-compat-api.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-This patch was copied from Debian.
-
---- xserver-xorg-video-intel-2.21.15.orig/src/compat-api.h
-+++ xserver-xorg-video-intel-2.21.15/src/compat-api.h
-@@ -158,4 +158,8 @@
- 	if ((d)->pScreen->SourceValidate) (d)->pScreen->SourceValidate(d, x, y, w, h)
- #endif
- 
-+#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,14,99,2,0)
-+#define DamageUnregister(d, dd) DamageUnregister(dd)
-+#endif
-+
- #endif
diff --git a/gnu/packages/patches/xf86-video-intel-glibc-2.20.patch b/gnu/packages/patches/xf86-video-intel-glibc-2.20.patch
deleted file mode 100644
index aeebfacdcd..0000000000
--- a/gnu/packages/patches/xf86-video-intel-glibc-2.20.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-Allow builds with glibc 2.20.
-Based on a patch by Peter Hutterer <peter.hutterer@who-t.net>.
-See <https://raw.githubusercontent.com/openembedded/oe-core/master/meta/recipes-graphics/xorg-driver/xf86-input-synaptics/always_include_xorg_server.h.patch>.
-
---- xf86-video-intel-2.21.15/src/intel_device.c.~1~	2013-08-09 16:58:48.000000000 -0400
-+++ xf86-video-intel-2.21.15/src/intel_device.c	2014-12-18 00:03:54.700759577 -0500
-@@ -33,6 +33,8 @@
- 
- #include <sys/ioctl.h>
- 
-+#include <xorg-server.h>
-+
- #include <pciaccess.h>
- #include <xf86.h>
- #include <xf86drm.h>
diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm
index 8cd433a93d..e51405bd9c 100644
--- a/gnu/packages/python.scm
+++ b/gnu/packages/python.scm
@@ -37,6 +37,7 @@
 ;;; Copyright © 2017 Carlo Zancanaro <carlo@zancanaro.id.au>
 ;;; Copyright © 2017 Frederick M. Muriithi <fredmanglis@gmail.com>
 ;;; Copyright © 2017 humanitiesNerd <catonano@gmail.com>
+;;; Copyright © 2017 Ben Sturmfels <ben@sturm.com.au>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -7322,14 +7323,14 @@ message digests and key derivation functions.")
 (define-public python-pyopenssl
   (package
     (name "python-pyopenssl")
-    (version "16.2.0")
+    (version "17.0.0")
     (source
      (origin
        (method url-fetch)
        (uri (pypi-uri "pyOpenSSL" version))
        (sha256
         (base32
-         "0vji4yrfshs15xpczbhzhasnjrwcarsqg87n98ixnyafnyxs6ybp"))
+         "1pdg1gpmkzj8yasg6cmkhcivxcdp4c12nif88y4qvsxq5ffzxas8"))
        (patches
         (search-patches "python-pyopenssl-skip-network-test.patch"))))
     (build-system python-build-system)
@@ -7347,7 +7348,7 @@ message digests and key derivation functions.")
     (inputs
      `(("openssl" ,openssl)))
     (native-inputs
-     `(("python-pytest" ,python-pytest)))
+     `(("python-pytest" ,python-pytest-3.0)))
     (home-page "https://github.com/pyca/pyopenssl")
     (synopsis "Python wrapper module around the OpenSSL library")
     (description
@@ -13965,3 +13966,36 @@ recognize TestCases.")
        (sha256
         (base32
          "17jlkdpqw22z1nyml5ybslilqkzmnk0dxxjml8bfghav1l5hbwd2"))))))
+
+(define-public python-fudge
+  (package
+    (name "python-fudge")
+    ;; 0.9.6 is the latest version suitable for testing the "fabric" Python 2
+    ;; package, which is currently the only use of this package.
+    (version "0.9.6")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "fudge" version))
+       (sha256
+        (base32
+         "185ia3vr3qk4f2s1a9hdxb8ci4qc0x0xidrad96pywg8j930qs9l"))))
+    (build-system python-build-system)
+    (arguments
+     `(#:tests? #f))     ;XXX: Tests require the NoseJS Python package.
+    (home-page "https://github.com/fudge-py/fudge")
+    (synopsis "Replace real objects with fakes/mocks/stubs while testing")
+    (description
+     "Fudge is a Python module for using fake objects (mocks and stubs) to
+test real ones.
+
+In readable Python code, you declare the methods available on your fake object
+and how they should be called.  Then you inject that into your application and
+start testing.  This declarative approach means you don’t have to record and
+playback actions and you don’t have to inspect your fakes after running code.
+If the fake object was used incorrectly then you’ll see an informative
+exception message with a traceback that points to the culprit.")
+    (license license:expat)))
+
+(define-public python2-fudge
+  (package-with-python2 python-fudge))
diff --git a/gnu/packages/qemu.scm b/gnu/packages/qemu.scm
index e0b4695f3a..82367269ff 100644
--- a/gnu/packages/qemu.scm
+++ b/gnu/packages/qemu.scm
@@ -69,23 +69,14 @@
 (define-public qemu
   (package
     (name "qemu")
-    (version "2.8.1")
+    (version "2.9.0")
     (source (origin
              (method url-fetch)
              (uri (string-append "http://wiki.qemu-project.org/download/qemu-"
                                  version ".tar.xz"))
              (sha256
               (base32
-               "0h342v4n44kh89yyfas4iazvhhsy5m5qk94vsjqpz5zpq1i2ykad"))
-             (patches (search-patches "qemu-CVE-2016-10155.patch"
-                                      "qemu-CVE-2017-5525.patch"
-                                      "qemu-CVE-2017-5526.patch"
-                                      "qemu-CVE-2017-5552.patch"
-                                      "qemu-CVE-2017-5578.patch"
-                                      "qemu-CVE-2017-5579.patch"
-                                      "qemu-CVE-2017-5856.patch"
-                                      "qemu-CVE-2017-5898.patch"
-                                      ))))
+               "08mhfs0ndbkyqgw7fjaa9vjxf4dinrly656f6hjzvmaz7hzc677h"))))
     (build-system gnu-build-system)
     (arguments
      '(;; Running tests in parallel can occasionally lead to failures, like:
diff --git a/gnu/packages/rust.scm b/gnu/packages/rust.scm
index a9710ba4d7..1217ec71ff 100644
--- a/gnu/packages/rust.scm
+++ b/gnu/packages/rust.scm
@@ -301,6 +301,8 @@ safety and thread safety guarantees.")
     ;; Dual licensed.
     (license (list license:asl2.0 license:expat))))
 
+;; This tries very hard not to get into a cyclic dependency like this:
+;;   cargo <- cargo-build-system <- cargo.
 (define-public cargo
   (package
     (name "cargo")
@@ -825,6 +827,11 @@ safety and thread safety guarantees.")
     (arguments
      `(#:cargo ,cargo-bootstrap
        #:tests? #f ; FIXME
+       #:modules
+       ((ice-9 match)
+        (srfi srfi-1) ; 'every
+        (guix build utils)
+        (guix build cargo-build-system))
        #:phases
        (modify-phases %standard-phases
          ;; Avoid cargo complaining about missmatched checksums.
@@ -833,30 +840,36 @@ safety and thread safety guarantees.")
          (delete 'patch-usr-bin-file)
          (add-after 'unpack 'unpack-submodule-sources
            (lambda* (#:key inputs #:allow-other-keys)
-             (let ((unpack (lambda (source target)
-                             (mkdir-p target)
-                             (with-directory-excursion target
-                               (zero? (system* "tar" "xf"
-                                               source
-                                               "--strip-components=1"))))))
+             (define (unpack source target)
+               (mkdir-p target)
+               (with-directory-excursion target
+                 (zero? (system* "tar" "xf"
+                                 source
+                                 "--strip-components=1"))))
+             (define (touch file-name)
+               (call-with-output-file file-name (const #t)))
+             (define (install-rust-library entry)
+               (match entry
+                 ((name . src)
+                  (if (string-prefix? "rust-" name)
+                    (let* ((rust-length (string-length "rust-"))
+                           (rust-name (string-drop name
+                                                   rust-length))
+                           (rsrc (string-append "vendor/"
+                                                rust-name))
+                           (unpack-status (unpack src rsrc)))
+                      (touch (string-append rsrc "/.cargo-ok"))
+                      (generate-checksums rsrc src)
+                      unpack-status)))
+                 (_ #t)))
                (mkdir "vendor")
-               (for-each (lambda (p)
-                           (let ((name (car p)))
-                             (if (string-prefix? "rust-" name)
-                               (let ((rsrc (string-append "vendor/"
-                                                           (string-drop name
-                                                                        (string-length "rust-")))))
-                                 (unpack (assoc-ref inputs name) rsrc)
-                                 (system* "touch" (string-append rsrc "/.cargo-ok"))
-                                 (generate-checksums rsrc (assoc-ref inputs name)))))) inputs))))
-         ;; Set CARGO_HOME to use the vendored dependencies.
-         (add-after 'unpack 'set-cargo-home
+               (every install-rust-library inputs)))
+         (add-after 'unpack 'set-environment-up
            (lambda* (#:key inputs #:allow-other-keys)
              (let* ((gcc (assoc-ref inputs "gcc"))
                     (cc (string-append gcc "/bin/gcc")))
-               (mkdir "cargohome")
-               (setenv "CARGO_HOME" (string-append (getcwd) "/cargohome"))
-               (call-with-output-file "cargohome/config"
+               (mkdir ".cargo")
+               (call-with-output-file ".cargo/config"
                  (lambda (p)
                    (format p "
 [source.crates-io]
@@ -868,7 +881,8 @@ directory = 'vendor'
 ")))
                (setenv "CMAKE_C_COMPILER" cc)
                (setenv "CC" cc))
-             #t)))))
+             #t))
+         (delete 'configure))))
     (home-page "https://github.com/rust-lang/cargo")
     (synopsis "Build tool and package manager for Rust")
     (description "Cargo is a tool that allows Rust projects to declare their
diff --git a/gnu/packages/sdl.scm b/gnu/packages/sdl.scm
index f73a26cff4..584731760f 100644
--- a/gnu/packages/sdl.scm
+++ b/gnu/packages/sdl.scm
@@ -140,7 +140,7 @@ system, such as sound redirection over the network.")
 (define-public sdl-gfx
   (package
     (name "sdl-gfx")
-    (version "2.0.24")
+    (version "2.0.26")
     (source (origin
               (method url-fetch)
               (uri
@@ -148,7 +148,7 @@ system, such as sound redirection over the network.")
                               version ".tar.gz"))
               (sha256
                (base32
-                "064islldm4r42lgj9fr4kbk66r7jmmakk9745hhyb1kmw71kib9h"))))
+                "0ijljhs0v99dj6y27hc10z6qchyp8gdp4199y6jzngy6dzxlzsvw"))))
     (build-system gnu-build-system)
     (propagated-inputs `(("sdl" ,sdl)))
     (synopsis "SDL graphics primitives library")
diff --git a/gnu/packages/selinux.scm b/gnu/packages/selinux.scm
new file mode 100644
index 0000000000..81c899f841
--- /dev/null
+++ b/gnu/packages/selinux.scm
@@ -0,0 +1,481 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2016, 2017 Ricardo Wurmus <rekado@elephly.net>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu packages selinux)
+  #:use-module ((guix licenses) #:prefix license:)
+  #:use-module (guix packages)
+  #:use-module (guix download)
+  #:use-module (guix utils)
+  #:use-module (guix build-system gnu)
+  #:use-module (guix build-system python)
+  #:use-module (gnu packages)
+  #:use-module (gnu packages admin)
+  #:use-module (gnu packages bison)
+  #:use-module (gnu packages docbook)
+  #:use-module (gnu packages flex)
+  #:use-module (gnu packages gettext)
+  #:use-module (gnu packages glib)
+  #:use-module (gnu packages linux)
+  #:use-module (gnu packages networking)
+  #:use-module (gnu packages pcre)
+  #:use-module (gnu packages pkg-config)
+  #:use-module (gnu packages python)
+  #:use-module (gnu packages swig)
+  #:use-module (gnu packages textutils)
+  #:use-module (gnu packages xml))
+
+;; Update the SELinux packages together!
+
+(define-public libsepol
+  (package
+    (name "libsepol")
+    (version "2.6")
+    (source (let ((release "20161014"))
+              (origin
+                (method url-fetch)
+                (uri (string-append "https://github.com/SELinuxProject/selinux/"
+                                    "archive/" release ".tar.gz"))
+                (file-name (string-append "selinux-" release ".tar.gz"))
+                (sha256
+                 (base32
+                  "1dpwynfb6n31928343blac4159g4jbrwxdp61q5yffmxpy3c3czi")))))
+    (build-system gnu-build-system)
+    (arguments
+     `(#:tests? #f ; tests require checkpolicy, which requires libsepol
+       #:test-target "test"
+       #:make-flags
+       (let ((out (assoc-ref %outputs "out")))
+         (list (string-append "PREFIX=" out)
+               (string-append "DESTDIR=" out)
+               (string-append "MAN3DIR=" out "/share/man/man3")
+               (string-append "MAN5DIR=" out "/share/man/man5")
+               (string-append "MAN8DIR=" out "/share/man/man8")
+               (string-append "LDFLAGS=-Wl,-rpath=" out "/lib")
+               "CC=gcc"))
+       #:phases
+       (modify-phases %standard-phases
+         (delete 'configure)
+         (add-after 'unpack 'enter-dir
+           (lambda _ (chdir ,name) #t)))))
+    (native-inputs
+     `(("flex" ,flex)))
+    (home-page "https://selinuxproject.org/")
+    (synopsis "Library for manipulating SELinux policies")
+    (description
+     "The libsepol library provides an API for the manipulation of SELinux
+binary policies.  It is used by @code{checkpolicy} (the policy compiler) and
+similar tools, and programs such as @code{load_policy}, which must perform
+specific transformations on binary policies (for example, customizing policy
+boolean settings).")
+    (license license:lgpl2.1+)))
+
+(define-public checkpolicy
+  (package (inherit libsepol)
+    (name "checkpolicy")
+    (arguments
+     `(#:tests? #f ; there is no check target
+       #:make-flags
+       (let ((out (assoc-ref %outputs "out")))
+         (list (string-append "PREFIX=" out)
+               (string-append "LDLIBS="
+                              (assoc-ref %build-inputs "libsepol")
+                              "/lib/libsepol.a "
+                              (assoc-ref %build-inputs "flex")
+                              "/lib/libfl.a")
+               "CC=gcc"))
+       #:phases
+       (modify-phases %standard-phases
+         (delete 'configure)
+         (add-after 'unpack 'enter-dir
+           (lambda _ (chdir ,name) #t)))))
+    (inputs
+     `(("libsepol" ,libsepol)))
+    (native-inputs
+     `(("bison" ,bison)
+       ("flex" ,flex)))
+    (synopsis "Check SELinux security policy configurations and modules")
+    (description
+     "This package provides the tools \"checkpolicy\" and \"checkmodule\".
+Checkpolicy is a program that checks and compiles a SELinux security policy
+configuration into a binary representation that can be loaded into the kernel.
+Checkmodule is a program that checks and compiles a SELinux security policy
+module into a binary representation.")
+    ;; GPLv2 only
+    (license license:gpl2)))
+
+(define-public libselinux
+  (package (inherit libsepol)
+    (name "libselinux")
+    (arguments
+     (substitute-keyword-arguments (package-arguments libsepol)
+       ((#:make-flags flags)
+        `(cons* "PYTHON=python3"
+                (string-append "PYSITEDIR="
+                               (assoc-ref %outputs "out")
+                               "/lib/python"
+                               ,(version-major+minor (package-version python))
+                               "/site-packages/")
+                ,flags))
+       ((#:phases phases)
+        `(modify-phases ,phases
+           (replace 'enter-dir
+             (lambda _ (chdir ,name) #t))
+           ;; libsepol.a is not located in this package's LIBDIR.
+           (add-after 'enter-dir 'patch-libsepol-path
+             (lambda* (#:key inputs #:allow-other-keys)
+               (substitute* "src/Makefile"
+                 (("\\$\\(LIBDIR\\)/libsepol.a")
+                  (string-append (assoc-ref inputs "libsepol")
+                                 "/lib/libsepol.a")))
+               #t))
+           (add-after 'enter-dir 'remove-Werror
+             (lambda _
+               ;; GCC complains about the fact that the output does not (yet)
+               ;; have an "include" directory, even though it is referenced.
+               (substitute* '("src/Makefile"
+                              "utils/Makefile")
+                 (("-Werror ") ""))
+               #t))
+           (add-after 'build 'pywrap
+             (lambda* (#:key make-flags #:allow-other-keys)
+               (zero? (apply system* "make" "pywrap" make-flags))))
+           (add-after 'install 'install-pywrap
+             (lambda* (#:key make-flags #:allow-other-keys)
+               (zero? (apply system* "make" "install-pywrap" make-flags))))))))
+    (inputs
+     `(("libsepol" ,libsepol)
+       ("pcre" ,pcre)
+       ;; For pywrap phase
+       ("python" ,python-wrapper)))
+    ;; These inputs are only needed for the pywrap phase.
+    (native-inputs
+     `(("swig" ,swig)
+       ("pkg-config" ,pkg-config)))
+    (synopsis "SELinux core libraries and utilities")
+    (description
+     "The libselinux library provides an API for SELinux applications to get
+and set process and file security contexts, and to obtain security policy
+decisions.  It is required for any applications that use the SELinux API, and
+used by all applications that are SELinux-aware.  This package also includes
+the core SELinux management utilities.")
+    (license license:public-domain)))
+
+(define-public libsemanage
+  (package (inherit libsepol)
+    (name "libsemanage")
+    (arguments
+     (substitute-keyword-arguments (package-arguments libsepol)
+       ((#:make-flags flags)
+        `(cons* "PYTHON=python3"
+                (string-append "PYSITEDIR="
+                               (assoc-ref %outputs "out")
+                               "/lib/python"
+                               ,(version-major+minor (package-version python))
+                               "/site-packages/")
+                ,flags))
+       ((#:phases phases)
+        `(modify-phases ,phases
+           (replace 'enter-dir
+             (lambda _ (chdir ,name) #t))
+           (add-after 'build 'pywrap
+             (lambda* (#:key make-flags #:allow-other-keys)
+               (zero? (apply system* "make" "pywrap" make-flags))))
+           (add-after 'install 'install-pywrap
+             (lambda* (#:key make-flags #:allow-other-keys)
+               (zero? (apply system* "make" "install-pywrap" make-flags))))))))
+    (inputs
+     `(("libsepol" ,libsepol)
+       ("libselinux" ,libselinux)
+       ("audit" ,audit)
+       ("ustr" ,ustr)
+       ;; For pywrap phase
+       ("python" ,python-wrapper)))
+    (native-inputs
+     `(("bison" ,bison)
+       ("flex" ,flex)
+       ;; For pywrap phase
+       ("swig" ,swig)
+       ("pkg-config" ,pkg-config)))
+    (synopsis "SELinux policy management libraries")
+    (description
+     "The libsemanage library provides an API for the manipulation of SELinux
+binary policies.")
+    (license license:lgpl2.1+)))
+
+(define-public secilc
+  (package (inherit libsepol)
+    (name "secilc")
+    (arguments
+     (substitute-keyword-arguments (package-arguments libsepol)
+       ((#:make-flags flags)
+        `(let ((docbook (assoc-ref %build-inputs "docbook-xsl")))
+           (cons (string-append "XMLTO=xmlto --skip-validation -x "
+                                docbook "/xml/xsl/docbook-xsl-"
+                                ,(package-version docbook-xsl)
+                                "/manpages/docbook.xsl")
+                 ,flags)))
+       ((#:phases phases)
+        `(modify-phases ,phases
+           (replace 'enter-dir
+             (lambda _ (chdir ,name) #t))))))
+    (inputs
+     `(("libsepol" ,libsepol)))
+    (native-inputs
+     `(("xmlto" ,xmlto)
+       ("docbook-xsl" ,docbook-xsl)))
+    (synopsis "SELinux common intermediate language (CIL) compiler")
+    (description "The SELinux CIL compiler is a compiler that converts the
+@dfn{common intermediate language} (CIL) into a kernel binary policy file.")
+    (license license:bsd-2)))
+
+(define-public python-sepolgen
+  (package (inherit libsepol)
+    (name "python-sepolgen")
+    (arguments
+     `(#:modules ((srfi srfi-1)
+                  (guix build gnu-build-system)
+                  (guix build utils))
+       ,@(substitute-keyword-arguments (package-arguments libsepol)
+           ((#:phases phases)
+            `(modify-phases ,phases
+               (replace 'enter-dir
+                 (lambda _ (chdir "sepolgen") #t))
+               ;; By default all Python files would be installed to
+               ;; $out/gnu/store/...-python-.../, so we override the
+               ;; PACKAGEDIR to fix this.
+               (add-after 'enter-dir 'fix-target-path
+                 (lambda* (#:key inputs outputs #:allow-other-keys)
+                   (let ((get-python-version
+                          ;; FIXME: copied from python-build-system
+                          (lambda (python)
+                            (let* ((version     (last (string-split python #\-)))
+                                   (components  (string-split version #\.))
+                                   (major+minor (take components 2)))
+                              (string-join major+minor ".")))))
+                     (substitute* "src/sepolgen/Makefile"
+                       (("^PACKAGEDIR.*")
+                        (string-append "PACKAGEDIR="
+                                       (assoc-ref outputs "out")
+                                       "/lib/python"
+                                       (get-python-version
+                                        (assoc-ref inputs "python"))
+                                       "/site-packages/sepolgen")))
+                     (substitute* "src/share/Makefile"
+                       (("\\$\\(DESTDIR\\)") (assoc-ref outputs "out"))))
+                   #t)))))))
+    (inputs
+     `(("python" ,python-wrapper)))
+    (native-inputs '())
+    (synopsis "Python module for generating SELinux policies")
+    (description
+     "This package contains a Python module that forms the core of
+@code{audit2allow}, a part of the package @code{policycoreutils}.  The
+sepolgen library contains: Reference Policy Representation, which are Objects
+for representing policies and the reference policy interfaces.  It has objects
+and algorithms for representing access and sets of access in an abstract way
+and searching that access.  It also has a parser for reference policy
+\"headers\".  It contains infrastructure for parsing SELinux related messages
+as produced by the audit system.  It has facilities for generating policy
+based on required access.")
+    ;; GPLv2 only
+    (license license:gpl2)))
+
+;; The latest 4.1.x version does not work with the latest 2.6 release of
+;; policycoreutils, so we use the last 4.0.x release.
+(define-public python-setools
+  (package
+    (name "python-setools")
+    (version "4.0.1")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "https://github.com/TresysTechnology/"
+                                  "setools/archive/" version ".tar.gz"))
+              (file-name (string-append name "-" version ".tar.gz"))
+              (sha256
+               (base32
+                "1zndpl4ck5c23p7s4sci06db89q1w87jig3jbd4f8s1ggy3lj82c"))))
+    (build-system python-build-system)
+    (arguments
+     `(#:tests? #f ; the test target causes a rebuild
+       #:phases
+       (modify-phases %standard-phases
+         (add-after 'unpack 'set-SEPOL-variable
+           (lambda* (#:key inputs #:allow-other-keys)
+             (setenv "SEPOL"
+                     (string-append (assoc-ref inputs "libsepol")
+                                    "/lib/libsepol.a"))))
+         (add-after 'unpack 'remove-Werror
+           (lambda _
+             (substitute* "setup.py"
+               (("'-Werror',") ""))
+             #t))
+         (add-after 'unpack 'fix-target-paths
+           (lambda* (#:key outputs #:allow-other-keys)
+             (substitute* "setup.py"
+               (("join\\(sys.prefix")
+                (string-append "join(\"" (assoc-ref outputs "out") "/\"")))
+             #t)))))
+    (propagated-inputs
+     `(("python-networkx" ,python-networkx)))
+    (inputs
+     `(("libsepol" ,libsepol)
+       ("libselinux" ,libselinux)))
+    (native-inputs
+     `(("bison" ,bison)
+       ("flex" ,flex)
+       ("swig" ,swig)))
+    (home-page "https://github.com/TresysTechnology/setools")
+    (synopsis "Tools for SELinux policy analysis")
+    (description "SETools is a collection of graphical tools, command-line
+tools, and libraries designed to facilitate SELinux policy analysis.")
+    ;; Some programs are under GPL, all libraries under LGPL.
+    (license (list license:lgpl2.1+
+                   license:gpl2+))))
+
+(define-public policycoreutils
+  (package (inherit libsepol)
+    (name "policycoreutils")
+    (source
+     (origin (inherit (package-source libsepol))
+             (patches (search-patches "policycoreutils-make-sepolicy-use-python3.patch"))
+             (patch-flags '("-p1" "-d" "policycoreutils"))))
+    (arguments
+     `(#:test-target "test"
+       #:make-flags
+       (let ((out (assoc-ref %outputs "out")))
+         (list "CC=gcc"
+               (string-append "PREFIX=" out)
+               (string-append "LOCALEDIR=" out "/share/locale")
+               (string-append "BASHCOMPLETIONDIR=" out
+                              "/share/bash-completion/completions")
+               "INSTALL=install -c -p"
+               "INSTALL_DIR=install -d"
+               ;; These ones are needed because some Makefiles define the
+               ;; directories relative to DESTDIR, not relative to PREFIX.
+               (string-append "SBINDIR=" out "/sbin")
+               (string-append "ETCDIR=" out "/etc")
+               (string-append "SYSCONFDIR=" out "/etc/sysconfig")
+               (string-append "MAN5DIR=" out "/share/man/man5")
+               (string-append "INSTALL_NLS_DIR=" out "/share/locale")
+               (string-append "AUTOSTARTDIR=" out "/etc/xdg/autostart")
+               (string-append "DBUSSERVICEDIR=" out "/share/dbus-1/services")
+               (string-append "SYSTEMDDIR=" out "/lib/systemd")
+               (string-append "INITDIR=" out "/etc/rc.d/init.d")
+               (string-append "SELINUXDIR=" out "/etc/selinux")))
+       #:phases
+       (modify-phases %standard-phases
+         (delete 'configure)
+         (add-after 'unpack 'enter-dir
+           (lambda _ (chdir ,name) #t))
+         (add-after 'enter-dir 'ignore-/usr-tests
+           (lambda* (#:key inputs #:allow-other-keys)
+             ;; The Makefile decides to build restorecond only if it finds the
+             ;; inotify header somewhere under /usr.
+             (substitute* "Makefile"
+               (("ifeq.*") "")
+               (("endif.*") ""))
+             ;; Rewrite lookup paths for header files.
+             (substitute* '("newrole/Makefile"
+                            "setfiles/Makefile"
+                            "run_init/Makefile")
+               (("/usr(/include/security/pam_appl.h)" _ file)
+                (string-append (assoc-ref inputs "pam") file))
+               (("/usr(/include/libaudit.h)" _ file)
+                (string-append (assoc-ref inputs "audit") file)))
+             #t))
+         (add-after 'enter-dir 'fix-glib-cflags
+           (lambda* (#:key inputs #:allow-other-keys)
+             (substitute* "restorecond/Makefile"
+               (("/usr(/include/glib-2.0|/lib/glib-2.0/include)" _ path)
+                (string-append (assoc-ref inputs "glib") path))
+               (("/usr(/include/dbus-1.0|/lib/dbus-1.0/include)" _ path)
+                (string-append (assoc-ref inputs "dbus") path
+                               " -I"
+                               (assoc-ref inputs "dbus-glib") path)))
+             #t))
+         (add-after 'enter-dir 'fix-linkage-with-libsepol
+           (lambda* (#:key inputs #:allow-other-keys)
+             (substitute* '("semodule_deps/Makefile"
+                            "sepolgen-ifgen/Makefile")
+               (("\\$\\(LIBDIR\\)")
+                (string-append (assoc-ref inputs "libsepol") "/lib/")))))
+         (add-after 'enter-dir 'fix-target-paths
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let ((out (assoc-ref outputs "out")))
+               (substitute* "audit2allow/sepolgen-ifgen"
+                 (("ATTR_HELPER = \"/usr/bin/sepolgen-ifgen-attr-helper\"")
+                  (string-append "ATTR_HELPER = \"" out
+                                 "/bin/sepolgen-ifgen-attr-helper\"")))
+               (substitute* "sepolicy/sepolicy/__init__.py"
+                 (("/usr/bin/sepolgen-ifgen")
+                  (string-append out "/bin/sepolgen-ifgen")))
+               (substitute* "sepolicy/Makefile"
+                 ;; By default all Python files would be installed to
+                 ;; $out/gnu/store/...-python-.../.
+                 (("setup.py install.*$")
+                  (string-append "setup.py install --prefix=" out "\n"))
+                 (("\\$\\(DESTDIR\\)/etc")
+                  (string-append out "/etc"))
+                 (("\\$\\(DESTDIR\\)/usr") out)))
+             #t))
+         (add-after 'install 'wrap-python-tools
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let* ((out (assoc-ref outputs "out"))
+                    (var (string-append out "/lib/python"
+                                        ,(version-major+minor (package-version python))
+                                        "/site-packages:"
+                                        (getenv "PYTHONPATH"))))
+               ;; The scripts' shebangs tell Python to ignore the PYTHONPATH,
+               ;; so we need to patch them before wrapping.
+               (for-each (lambda (file)
+                           (let ((path (string-append out "/" file)))
+                             (substitute* path
+                               (("bin/python -Es") "bin/python -s"))
+                             (wrap-program path
+                               `("PYTHONPATH" ":" prefix (,var)))))
+                         '("bin/audit2allow"
+                           "bin/chcat"
+                           "bin/sandbox"
+                           "bin/sepolgen-ifgen"
+                           "bin/sepolicy"
+                           "sbin/semanage")))
+             #t)))))
+    (inputs
+     `(("python" ,python-wrapper)
+       ("audit" ,audit)
+       ("pam" ,linux-pam)
+       ("libsepol" ,libsepol)
+       ("libselinux" ,libselinux)
+       ("libsemanage" ,libsemanage)
+       ("python-sepolgen" ,python-sepolgen)
+       ("python-setools" ,python-setools)
+       ("python-ipy" ,python-ipy)
+       ("libcap-ng" ,libcap-ng)
+       ("pcre" ,pcre)
+       ("dbus" ,dbus)
+       ("dbus-glib" ,dbus-glib)
+       ("glib" ,glib)))
+    (native-inputs
+     `(("gettext" ,gettext-minimal)))
+    (synopsis "SELinux core utilities")
+    (description "The policycoreutils package contains the core utilities that
+are required for the basic operation of an SELinux-enabled GNU system and its
+policies.  These utilities include @code{load_policy} to load policies,
+@code{setfiles} to label file systems, @code{newrole} to switch roles, and
+@code{run_init} to run service scripts in their proper context.")
+    (license license:gpl2+)))
diff --git a/gnu/packages/serialization.scm b/gnu/packages/serialization.scm
index eb3cb26759..5908f50d68 100644
--- a/gnu/packages/serialization.scm
+++ b/gnu/packages/serialization.scm
@@ -4,6 +4,7 @@
 ;;; Copyright © 2016 David Craven <david@craven.ch>
 ;;; Copyright © 2016 Marius Bakke <mbakke@fastmail.com>
 ;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2017 Corentin Bocquillon <corentin@nybble.fr>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -35,7 +36,8 @@
   #:use-module (gnu packages documentation)
   #:use-module (gnu packages lua)
   #:use-module (gnu packages pkg-config)
-  #:use-module (gnu packages python))
+  #:use-module (gnu packages python)
+  #:use-module (gnu packages perl))
 
 (define-public cereal
   (package
@@ -287,3 +289,24 @@ it a convenient format to store user input files.")
      "Cap'n Proto is a very fast data interchange format and capability-based
 RPC system.  Think JSON, except binary.  Or think Protocol Buffers, except faster.")
     (license license:expat)))
+
+(define-public libbson
+  (package
+    (name "libbson")
+    (version "1.6.2")
+    (source
+      (origin
+        (method url-fetch)
+        (uri (string-append "https://github.com/mongodb/libbson/releases/"
+                             "download/" version "/libbson-" version ".tar.gz"))
+        (sha256
+         (base32
+          "1fj4554msq0rrz14snbj908dzqj46gh7jg9w9j0akn2b7q911m5a"))))
+    (build-system gnu-build-system)
+    (native-inputs `(("perl" ,perl)))
+    (home-page "http://mongoc.org/libbson/current/index.html")
+    (synopsis "C BSON library")
+    (description "Libbson can create and parse BSON documents.  It can also
+convert JSON documents to BSON and the opposite.  BSON stands for Binary JSON,
+it is comparable to protobuf.")
+    (license license:asl2.0)))
diff --git a/gnu/packages/ssh.scm b/gnu/packages/ssh.scm
index 9c18a7ab39..135083ad22 100644
--- a/gnu/packages/ssh.scm
+++ b/gnu/packages/ssh.scm
@@ -52,7 +52,8 @@
   #:use-module (guix download)
   #:use-module (guix git-download)
   #:use-module ((guix licenses) #:prefix license:)
-  #:use-module (guix packages))
+  #:use-module (guix packages)
+  #:use-module (srfi srfi-1))
 
 (define-public libssh
   (package
@@ -265,6 +266,27 @@ programs written in GNU Guile interpreter.  It is a wrapper to the underlying
 libssh library.")
     (license license:gpl3+)))
 
+(define-public guile2.2-ssh
+  ;; This is a snapshot of a unofficial copy of Guile-SSH, which hopefully
+  ;; reflects the upcoming release well enough.
+  (let ((commit "926a0843626f89e3db02d01a6b01cc1f0d9cefcf")
+        (revision "0"))
+    (package
+      (inherit guile-ssh)
+      (name "guile2.2-ssh")
+      (version (string-append "0.10.2." revision "." (string-take commit 7)))
+      (source (origin
+                (method git-fetch)
+                (uri (git-reference
+                      (url "https://notabug.org/civodul/guile-ssh/")
+                      (commit commit)))
+                (file-name (git-file-name name version))
+                (sha256
+                 (base32
+                  "0hf28macq8d1w05g0xy2lw1s5vzmcrixh7m43x7qvvdd31c998ip"))))
+      (inputs `(("guile" ,guile-2.2)
+                ,@(alist-delete "guile" (package-inputs guile-ssh)))))))
+
 (define-public corkscrew
   (package
     (name "corkscrew")
diff --git a/gnu/packages/statistics.scm b/gnu/packages/statistics.scm
index 18136f1396..4882ca7bac 100644
--- a/gnu/packages/statistics.scm
+++ b/gnu/packages/statistics.scm
@@ -262,14 +262,14 @@ available, greatly increasing its breadth and scope.")
 (define-public r-boot
   (package
     (name "r-boot")
-    (version "1.3-18")
+    (version "1.3-19")
     (source
      (origin
        (method url-fetch)
        (uri (cran-uri "boot" version))
        (sha256
         (base32
-         "0pi348vvgzn1ny54yxhw6kq6nl7rx9bpr9ji1a6wqs8ah5zj7z8j"))))
+         "16hsw4bw9pkfc2lqxfwycm1sbvbrm4linvm0ci71n8sxc7srvkis"))))
     (build-system r-build-system)
     (home-page "http://cran.r-project.org/web/packages/boot")
     (synopsis "Bootstrap functions for R")
@@ -283,14 +283,14 @@ D.V. Hinkley (1997, CUP), originally written by Angelo Canty for S.")
 (define-public r-mass
   (package
     (name "r-mass")
-    (version "7.3-45")
+    (version "7.3-47")
     (source
      (origin
        (method url-fetch)
        (uri (cran-uri "MASS" version))
        (sha256
         (base32
-         "13lp5919h2bnpmf8rbmkar8a41yx62fnx66pkvljvqf60wa29qsx"))))
+         "1gy6z7ly9wn86rfn9xrmqiqq1ijw3pkasrr2299kbzsgx2mwsi7d"))))
     (properties `((upstream-name . "MASS")))
     (build-system r-build-system)
     (home-page "http://www.stats.ox.ac.uk/pub/MASS4/")
@@ -514,14 +514,14 @@ single hidden layer, and for multinomial log-linear models.")
 (define-public r-rpart
   (package
     (name "r-rpart")
-    (version "4.1-10")
+    (version "4.1-11")
     (source
      (origin
        (method url-fetch)
        (uri (cran-uri "rpart" version))
        (sha256
         (base32
-         "119dvh2cpab4vq9blvbkil5hgq6w018amiwlda3ii0fki39axpf5"))))
+         "165djqj7lk81jr7z5fwccq3h7ayys26hx1kj9hndvg2rkyaq1arq"))))
     (build-system r-build-system)
     (home-page "http://cran.r-project.org/web/packages/rpart")
     (synopsis "Recursive partitioning and regression trees")
@@ -1124,13 +1124,13 @@ considerably faster, produces smaller files, and leaves text as is.")
 (define-public r-assertthat
   (package
     (name "r-assertthat")
-    (version "0.1")
+    (version "0.2.0")
     (source (origin
               (method url-fetch)
               (uri (cran-uri "assertthat" version))
               (sha256
                (base32
-                "0dwsqajyglfscqilj843qfqn1ndbqpswa7b4l1d633qjk9d68qqk"))))
+                "1wp5znk3xy338x6hknppk702jn596yr735d9i7c3wabm3sdzfgnp"))))
     (build-system r-build-system)
     (home-page "https://github.com/hadley/assertthat")
     (synopsis "Easy pre and post assertions")
@@ -1279,13 +1279,13 @@ data derived from /etc/mime.types in UNIX-type systems.")
 (define-public r-markdown
   (package
     (name "r-markdown")
-    (version "0.7.7")
+    (version "0.8")
     (source (origin
               (method url-fetch)
               (uri (cran-uri "markdown" version))
               (sha256
                (base32
-                "00j1hlib3il50azs2vlcyhi0bjpx1r50mxr9w9dl5g1bwjjc71hb"))))
+                "1vcgsh2m2f5kfgappgg71nbf04ff0j1sbk668krjs3r2n89dk3sk"))))
     (build-system r-build-system)
     ;; Skip check phase because the tests require the r-knitr package to be
     ;; installed. This prevents installation failures. Knitr normally
@@ -1417,13 +1417,13 @@ understand the language at a deeper level.")
 (define-public r-memoise
   (package
     (name "r-memoise")
-    (version "1.0.0")
+    (version "1.1.0")
     (source (origin
               (method url-fetch)
               (uri (cran-uri "memoise" version))
               (sha256
                (base32
-                "0sq2dhpvxy17v1baj256r0jnygdy3m5a8x4zh6vhv29957qnq6zx"))))
+                "034qfc2xlh30x1q2vya239w34a3ir3y2fwnx2agbgbi6592zjxmj"))))
     (build-system r-build-system)
     (propagated-inputs
      `(("r-digest" ,r-digest)))
@@ -2443,13 +2443,13 @@ well as additional utilities such as panel and axis annotation functions.")
 (define-public r-rcpparmadillo
   (package
     (name "r-rcpparmadillo")
-    (version "0.7.700.0.0")
+    (version "0.7.800.2.0")
     (source (origin
               (method url-fetch)
               (uri (cran-uri "RcppArmadillo" version))
               (sha256
                (base32
-                "03cvl2xgmvh4sylw7ff7s020y7k2wzyj34l0zngm09qs44pa9q0m"))))
+                "025lh504nw7ir1f2xsqnvfkq9rg0rb2xzfn3a2s0b2a9snqdzzwr"))))
     (properties `((upstream-name . "RcppArmadillo")))
     (build-system r-build-system)
     (propagated-inputs
@@ -3151,14 +3151,14 @@ the way current RNG settings can be changed.")
 (define-public r-rtsne
   (package
     (name "r-rtsne")
-    (version "0.11")
+    (version "0.13")
     (source
      (origin
        (method url-fetch)
        (uri (cran-uri "Rtsne" version))
        (sha256
         (base32
-         "0zi4nxgpiv1gpdmcnqdhz5kymzp8m5xj02zpf290p1yyydl76bhy"))))
+         "17crbdi80q4g2pwp9v7j3bdaznk96qlrqx01zvj3wwqippizyfqw"))))
     (properties `((upstream-name . "Rtsne")))
     (build-system r-build-system)
     (propagated-inputs
@@ -3431,13 +3431,13 @@ persistent (on the file system).")
 (define-public r-r-rsp
   (package
     (name "r-r-rsp")
-    (version "0.40.0")
+    (version "0.41.0")
     (source (origin
               (method url-fetch)
               (uri (cran-uri "R.rsp" version))
               (sha256
                (base32
-                "1hz5fnxz30m3cc7x7ha1swx4pn8c2244z6ka6v9m3l5lpdgc1367"))))
+                "01l430avj5ggmdsla2kiriix72g0dlzx9klniq321bs0za808v3c"))))
     (properties `((upstream-name . "R.rsp")))
     (build-system r-build-system)
     (propagated-inputs
@@ -3481,13 +3481,13 @@ t-probabilities, quantiles, random deviates and densities.")
 (define-public r-matrixstats
   (package
     (name "r-matrixstats")
-    (version "0.52.1")
+    (version "0.52.2")
     (source (origin
               (method url-fetch)
               (uri (cran-uri "matrixStats" version))
               (sha256
                (base32
-                "0ihxnbbc1czfbccm8mrh7hjwdik3y90964xhbjday6fci0xjcsi5"))))
+                "19fjf19cr0p3j9pj17myz39zpi5bh7ci72db3la9my09n6k6mnir"))))
     (properties `((upstream-name . "matrixStats")))
     (build-system r-build-system)
     (native-inputs
@@ -4150,13 +4150,13 @@ estimation) corresponding to the book: Wand, M.P.  and Jones, M.C. (1995)
 (define-public r-zoo
   (package
     (name "r-zoo")
-    (version "1.7-14")
+    (version "1.8-0")
     (source (origin
               (method url-fetch)
               (uri (cran-uri "zoo" version))
               (sha256
                (base32
-                "167m142rwwfy8b9hnfc3fi28dcsdjk61g1crqhll6sh5xmgnfn28"))))
+                "0mqklbx92ifwa0awm7gpm4r9dvwa09p55zjxjnypiqsxy532r4h9"))))
     (build-system r-build-system)
     (propagated-inputs
      `(("r-lattice" ,r-lattice)))
@@ -4371,14 +4371,14 @@ published by the statistics blog FiveThirtyEight.")
 (define-public r-compquadform
   (package
     (name "r-compquadform")
-    (version "1.4.2")
+    (version "1.4.3")
     (source
      (origin
        (method url-fetch)
        (uri (cran-uri "CompQuadForm" version))
        (sha256
         (base32
-         "0bsgbdblxpv57mbwnf51xyiydp2bqyxkg4zzwqki85cv5xqlrq1n"))))
+         "1i30hrqdk64q17vsn918c3q79brchgx2wzh1gbsgbn0dh1ncabq4"))))
     (properties `((upstream-name . "CompQuadForm")))
     (build-system r-build-system)
     (home-page "http://cran.r-project.org/web/packages/CompQuadForm")
@@ -4879,19 +4879,20 @@ using modular prediction and response module classes.")
 (define-public r-quantreg
   (package
     (name "r-quantreg")
-    (version "5.29")
+    (version "5.33")
     (source
      (origin
        (method url-fetch)
        (uri (cran-uri "quantreg" version))
        (sha256
         (base32
-         "098gy8xv9kcl5y0cm93b8chr5sm6crrdxi20bkx9lmwmybl3himv"))))
+         "1dirmxa4cd05nb0yv0ga6ivw5hkr2zr2cb2lixl1nb6amqn024is"))))
     (build-system r-build-system)
     (native-inputs
      `(("gfortran" ,gfortran)))
     (propagated-inputs
-     `(("r-matrixmodels" ,r-matrixmodels)
+     `(("r-matrix" ,r-matrix)
+       ("r-matrixmodels" ,r-matrixmodels)
        ("r-sparsem" ,r-sparsem)))
     (home-page "http://www.r-project.org")
     (synopsis "Quantile regression")
@@ -4932,20 +4933,22 @@ algorithms.")
 (define-public r-lme4
   (package
     (name "r-lme4")
-    (version "1.1-12")
+    (version "1.1-13")
     (source
      (origin
        (method url-fetch)
        (uri (cran-uri "lme4" version))
        (sha256
         (base32
-         "0j60l5kgx1wvw2wm3jwfqwi63hammaq8gfcxzwa4h552likvaxi9"))))
+         "13j4a721rx0272pdxrz6nabjv56xb6srklq5w4z1abc82lyvda2z"))))
     (build-system r-build-system)
     (native-inputs
      `(("r-rcpp" ,r-rcpp)
        ("r-rcppeigen" ,r-rcppeigen)))
     (propagated-inputs
-     `(("r-minqa" ,r-minqa)
+     `(("r-lattice" ,r-lattice)
+       ("r-matrix" ,r-matrix)
+       ("r-minqa" ,r-minqa)
        ("r-nloptr" ,r-nloptr)
        ("r-mass" ,r-mass)
        ("r-nlme" ,r-nlme)))
@@ -5010,20 +5013,22 @@ to Applied regression, Second Edition, Sage, 2011.")
 (define-public r-caret
   (package
     (name "r-caret")
-    (version "6.0-73")
+    (version "6.0-76")
     (source
      (origin
        (method url-fetch)
        (uri (cran-uri "caret" version))
        (sha256
         (base32
-         "1jzaqwv4glyqqnfbpalgajd0ag866247vvdh5i83ffqs1yhs984h"))))
+         "1w31xzpmj8p6r6s7s1vwnjxainq54bbh4cqm177ba0myv69hh8cc"))))
     (build-system r-build-system)
     (propagated-inputs
      `(("r-car" ,r-car)
        ("r-foreach" ,r-foreach)
        ("r-ggplot2" ,r-ggplot2)
+       ("r-lattice" ,r-lattice)
        ("r-modelmetrics" ,r-modelmetrics)
+       ("r-nlme" ,r-nlme)
        ("r-plyr" ,r-plyr)
        ("r-reshape2" ,r-reshape2)))
     (home-page "https://github.com/topepo/caret")
diff --git a/gnu/packages/suckless.scm b/gnu/packages/suckless.scm
index 223a17f443..a87e665d2b 100644
--- a/gnu/packages/suckless.scm
+++ b/gnu/packages/suckless.scm
@@ -174,7 +174,7 @@ numbers of user-defined menu items efficiently.")
     (source
      (origin
        (method url-fetch)
-       (uri (string-append "http://dl.2f30.org/releases/"
+       (uri (string-append "https://dl.2f30.org/releases/"
                            name "-" version ".tar.gz"))
        (sha256
         (base32
@@ -189,7 +189,7 @@ numbers of user-defined menu items efficiently.")
        ("libxkbfile" ,libxkbfile)
        ("alsa-lib" ,alsa-lib)
        ("libmpdclient" ,libmpdclient)))
-    (home-page "http://git.2f30.org/spoon/")
+    (home-page "https://git.2f30.org/spoon/")
     (synopsis "Set dwm status")
     (description
      "Spoon can be used to set the dwm status.")
@@ -355,7 +355,7 @@ few minutes.")
     (source
      (origin
        (method url-fetch)
-       (uri (string-append "http://dl.2f30.org/releases/"
+       (uri (string-append "https://dl.2f30.org/releases/"
                            name "-" version ".tar.gz"))
        (sha256
         (base32
@@ -367,7 +367,7 @@ few minutes.")
                           (string-append "PREFIX=" %output))))
     (inputs
      `(("libx11" ,libx11)))
-    (home-page "http://git.2f30.org/xbattmon/")
+    (home-page "https://git.2f30.org/xbattmon/")
     (synopsis "Simple battery monitor for X")
     (description
      "Xbattmon is a simple battery monitor for X.")
@@ -380,7 +380,7 @@ few minutes.")
     (source
      (origin
        (method url-fetch)
-       (uri (string-append "http://dl.2f30.org/releases/"
+       (uri (string-append "https://dl.2f30.org/releases/"
                            name "-" version ".tar.gz"))
        (sha256
         (base32
@@ -393,7 +393,7 @@ few minutes.")
        #:phases
        (modify-phases %standard-phases
          (delete 'configure)))) ; No configure script
-    (home-page "http://git.2f30.org/wificurse/")
+    (home-page "https://git.2f30.org/wificurse/")
     (synopsis "Wifi DoS attack tool")
     (description
      "Wificurses listens for beacons sent from wireless access points
@@ -413,7 +413,7 @@ drivers capable of injecting packets in wireless networks.")
     (source
      (origin
        (method url-fetch)
-       (uri (string-append "http://dl.2f30.org/releases/"
+       (uri (string-append "https://dl.2f30.org/releases/"
                            name "-" version ".tar.gz"))
        (sha256
         (base32
@@ -426,7 +426,7 @@ drivers capable of injecting packets in wireless networks.")
        #:phases
        (modify-phases %standard-phases
          (delete 'configure)))) ; No configure script
-    (home-page "http://2f30.org")
+    (home-page "https://2f30.org/")
     (synopsis "Commandline utility which scrolls text")
     (description
      "Skroll is a small utility that you can use to make a text scroll.
@@ -441,7 +441,7 @@ left.")
     (source
      (origin
        (method url-fetch)
-       (uri (string-append "http://dl.2f30.org/releases/"
+       (uri (string-append "https://dl.2f30.org/releases/"
                            name "-" version ".tar.gz"))
        (sha256
         (base32
@@ -454,7 +454,7 @@ left.")
        #:phases
        (modify-phases %standard-phases
          (delete 'configure)))) ; No configure script
-    (home-page "http://git.2f30.org/sbm/")
+    (home-page "https://git.2f30.org/sbm/")
     (synopsis "Simple bandwidth monitor")
     (description
      "Sbm is a simple bandwidth monitor.")
@@ -467,7 +467,7 @@ left.")
     (source
      (origin
        (method url-fetch)
-       (uri (string-append "http://dl.2f30.org/releases/"
+       (uri (string-append "https://dl.2f30.org/releases/"
                            name "-" version ".tar.gz"))
        (sha256
         (base32
@@ -483,7 +483,7 @@ left.")
     (inputs
      `(("cups-minimal" ,cups-minimal)
        ("zlib" ,zlib)))
-    (home-page "http://git.2f30.org/prout/")
+    (home-page "https://git.2f30.org/prout/")
     (synopsis "Smaller lp command")
     (description
      "Prout (PRint OUT) is a small utility one can use to send
@@ -500,7 +500,7 @@ cups server to be installed.")
     (source
      (origin
        (method url-fetch)
-       (uri (string-append "http://dl.2f30.org/releases/"
+       (uri (string-append "https://dl.2f30.org/releases/"
                            name "-" version ".tar.gz"))
        (sha256
         (base32
@@ -519,7 +519,7 @@ cups server to be installed.")
                (("lcurses") "lncurses")))))))
     (inputs
      `(("ncurses" ,ncurses)))
-    (home-page "http://git.2f30.org/noice/")
+    (home-page "https://git.2f30.org/noice/")
     (synopsis "Small file browser")
     (description
      "Noice is a small curses-based file browser.")
@@ -550,7 +550,7 @@ cups server to be installed.")
        #:phases
        (modify-phases %standard-phases
          (delete 'configure)))) ; No configure script
-    (home-page "http://git.2f30.org/human/")
+    (home-page "https://git.2f30.org/human/")
     (synopsis "Convert bytes to human readable formats")
     (description
      "Human is a small program which translate numbers into a
@@ -567,7 +567,7 @@ environment variable.")
     (source
      (origin
        (method url-fetch)
-       (uri (string-append "http://dl.2f30.org/releases/"
+       (uri (string-append "https://dl.2f30.org/releases/"
                            name "-" version ".tar.gz"))
        (sha256
         (base32
@@ -580,22 +580,22 @@ environment variable.")
        #:phases
        (modify-phases %standard-phases
          (delete 'configure)))) ; No configure script
-    (home-page "http://git.2f30.org/fortify-headers/")
+    (home-page "https://git.2f30.org/fortify-headers/")
     (synopsis "Standalone fortify-source implementation")
     (description
      "This is a standalone implementation of fortify source.  It provides
 compile time buffer checks.  It is libc-agnostic and simply overlays the
 system headers by using the @code{#include_next} extension found in GCC.  It was
-initially intended to be used on musl based Linux distributions.
+initially intended to be used on musl-based Linux distributions.
 
 @itemize
 @item It is portable, works on *BSD, Linux, Solaris and possibly others.
 @item It will only trap non-conformant programs.  This means that fortify
   level 2 is treated in the same way as level 1.
 @item Avoids making function calls when undefined behaviour has already been
-  invoked.  This is handled by using __builtin_trap().
-@item Support for out-of-bounds read interfaces, such as send(), write(),
-  fwrite() etc.
+  invoked.  This is handled by using @code{__builtin_trap()}.
+@item Support for out-of-bounds read interfaces, such as @code{send()},
+  @code{write()}, @code{fwrite()}, etc.
 @item No ABI is enforced.  All of the fortify check functions are inlined
   into the resulting binary.
 @end itemize\n")
@@ -608,7 +608,7 @@ initially intended to be used on musl based Linux distributions.
     (source
      (origin
        (method url-fetch)
-       (uri (string-append "http://dl.2f30.org/releases/"
+       (uri (string-append "https://dl.2f30.org/releases/"
                            name "-" version ".tar.gz"))
        (sha256
         (base32
@@ -623,7 +623,7 @@ initially intended to be used on musl based Linux distributions.
          (delete 'configure)))) ; No configure script
     (inputs
      `(("libpng" ,libpng)))
-    (home-page "http://git.2f30.org/colors/")
+    (home-page "https://git.2f30.org/colors/")
     (synopsis "Extract colors from pictures")
     (description
      "Extract colors from PNG files.  It is similar to
diff --git a/gnu/packages/tls.scm b/gnu/packages/tls.scm
index 1c99a3ad75..50e9de4806 100644
--- a/gnu/packages/tls.scm
+++ b/gnu/packages/tls.scm
@@ -442,6 +442,11 @@ required structures.")
        (base32
         "0c4awq45cl757fv7f7f75i5i0ibc6v7ns13n7xvfak7chv2lrqql"))))
     (build-system gnu-build-system)
+    (arguments
+     ;; Do as if 'getentropy' was missing since older Linux kernels lack it
+     ;; and libc would return ENOSYS, which is not properly handled.
+     ;; See <https://lists.gnu.org/archive/html/guix-devel/2017-04/msg00235.html>.
+     '(#:configure-flags '("ac_cv_func_getentropy=no")))
     (native-search-paths
       ;; FIXME: These two variables must designate a single file or directory
       ;; and are not actually "search paths."  In practice it works OK in
diff --git a/gnu/packages/tmux.scm b/gnu/packages/tmux.scm
index c6a9ca8cae..5b92df88ae 100644
--- a/gnu/packages/tmux.scm
+++ b/gnu/packages/tmux.scm
@@ -2,6 +2,7 @@
 ;;; Copyright © 2013 Cyril Roelandt <tipecaml@gmail.com>
 ;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2016 Matthew Jordan <matthewjordandevops@yandex.com>
+;;; Copyright © 2017 Vasile Dumitrascu <va511e@yahoo.com>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -32,7 +33,7 @@
 (define-public tmux
   (package
     (name "tmux")
-    (version "2.3")
+    (version "2.4")
     (source (origin
              (method url-fetch)
              (uri (string-append
@@ -40,7 +41,7 @@
                     version "/tmux-" version ".tar.gz"))
              (sha256
               (base32
-               "0aw5fcav8pa70ym391n4g6mh5vir34x35xhb09zdwhhg5w9kwcam"))))
+               "0jdkk7vncwabrp85lw3msh2y02dc2k0qz5h4hka9s38x4c9nnzbm"))))
     (build-system gnu-build-system)
     (inputs
      `(("libevent" ,libevent)
diff --git a/gnu/packages/upnp.scm b/gnu/packages/upnp.scm
index 9be9741202..a3a6e848fb 100644
--- a/gnu/packages/upnp.scm
+++ b/gnu/packages/upnp.scm
@@ -28,14 +28,14 @@
 (define-public miniupnpc
   (package
     (name "miniupnpc")
-    (version "2.0.20161216")
+    (version "2.0.20170421")
     (source
      (origin
        (method url-fetch)
        (uri (string-append "https://miniupnp.tuxfamily.org/files/"
                            name "-" version ".tar.gz"))
        (sha256
-        (base32 "0gpxva9jkjvqwawff5y51r6bmsmdhixl3i5bmzlqsqpwsq449q81"))))
+        (base32 "0n11m2wq812zms5b21h8ihw1kbyaihj9nqjiida0hskf4dmw4m13"))))
     (build-system gnu-build-system)
     (native-inputs
      `(("python" ,python-2)))
@@ -45,8 +45,7 @@
      ;; the configure phase.
      '(#:make-flags
        (list
-        (string-append
-         "SH=" (assoc-ref %build-inputs "bash") "/bin/sh")
+        (string-append "SH=" (assoc-ref %build-inputs "bash") "/bin/sh")
         (string-append "INSTALLPREFIX=" (assoc-ref %outputs "out"))
         "CC=gcc"
 
@@ -65,11 +64,12 @@
     (synopsis "UPnP protocol client library")
     (description
      "The MiniUPnPc client library facilitates access to the services provided
-by any Universal Plug and Play (UPnP) Internet Gateway Device (IGD) present on
-the network.  In UPnP terminology, MiniUPnPc is a UPnP Control Point.  It is
-useful whenever an application needs to listen for incoming connections while
-running behind a UPnP-enabled router or firewall.  Such applications include
-peer-to-peer applications, active-mode FTP clients, DCC file transfers over
-IRC, instant messaging, network games, and most server software.")
+by any @dfn{Universal Plug and Play} (UPnP) @dfn{Internet Gateway Device} (IGD)
+present on the network.  In UPnP terminology, MiniUPnPc is a UPnP Control Point.
+
+It is useful whenever an application needs to listen for incoming connections
+while running behind a UPnP-enabled router or firewall.  Such applications
+include peer-to-peer applications, active-mode FTP clients, DCC file transfers
+over IRC, instant messaging, network games, and most server software.")
     (license
      (x11-style "file://LICENSE" "See 'LICENSE' file in the distribution"))))
diff --git a/gnu/packages/version-control.scm b/gnu/packages/version-control.scm
index 45b9e92404..e0770dc589 100644
--- a/gnu/packages/version-control.scm
+++ b/gnu/packages/version-control.scm
@@ -11,6 +11,8 @@
 ;;; Copyright © 2015 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2016 Leo Famulari <leo@famulari.name>
 ;;; Copyright © 2016, 2017 ng0 <contact.ng0@cryptolab.net>
+;;; Copyright © 2017 Tobias Geerinckx-Rice <me@tobias.gr>
+;;; Copyright © 2017 Vasile Dumitrascu <va511e@yahoo.com>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -167,7 +169,7 @@ as well as the classic centralized workflow.")
 
                      ;; By default 'make install' creates hard links for
                      ;; things in 'libexec/git-core', which leads to huge
-                     ;; nars; see <http://bugs.gnu.org/21949>.
+                     ;; nars; see <https://bugs.gnu.org/21949>.
                      "NO_INSTALL_HARDLINKS=indeed")
       #:test-target "test"
       #:tests? #f ; FIXME: Many tests are failing
@@ -305,21 +307,21 @@ as well as the classic centralized workflow.")
     "Git is a free distributed version control system designed to handle
 everything from small to very large projects with speed and efficiency.")
    (license license:gpl2)
-   (home-page "http://git-scm.com/")))
+   (home-page "https://git-scm.com/")))
 
 ;; Some dependent packages directly access internal interfaces which
-;; have changed in 2.10
-(define-public git@2.9
+;; have changed in 2.12
+(define-public git@2.10
   (package
     (inherit git)
-    (version "2.9.3")
+    (version "2.10.2")
    (source (origin
             (method url-fetch)
             (uri (string-append "mirror://kernel.org/software/scm/git/git-"
                                 version ".tar.xz"))
             (sha256
              (base32
-              "0qzs681a64k3shh5p0rg41l1z16fbk5sj0xga45k34hp1hsp654z"))))))
+              "0wc64dzcxrzgi6kwcljz6y3cwm3ajdgf6aws7g58azbhvl1jk04l"))))))
 
 (define-public libgit2
   (package
@@ -411,11 +413,11 @@ write native speed custom Git applications in any language with bindings.")
     (home-page "https://www.agwa.name/projects/git-crypt")
     (synopsis "Transparent encryption of files in a git repository")
     (description "git-crypt enables transparent encryption and decryption of
-files in a git repository. Files which you choose to protect are encrypted when
-committed, and decrypted when checked out. git-crypt lets you freely share a
-repository containing a mix of public and private content. git-crypt gracefully
+files in a git repository.  Files which you choose to protect are encrypted when
+committed, and decrypted when checked out.  git-crypt lets you freely share a
+repository containing a mix of public and private content.  git-crypt gracefully
 degrades, so developers without the secret key can still clone and commit to a
-repository with encrypted files. This lets you store your secret material (such
+repository with encrypted files.  This lets you store your secret material (such
 as keys or passwords) in the same repository as your code, without requiring you
 to lock down your entire repository.")
     (license license:gpl3+)))
@@ -423,7 +425,7 @@ to lock down your entire repository.")
 (define-public cgit
   (package
     (name "cgit")
-    (version "1.0")
+    (version "1.1")
     (source (origin
               (method url-fetch)
               (uri (string-append
@@ -431,7 +433,7 @@ to lock down your entire repository.")
                     version ".tar.xz"))
               (sha256
                (base32
-                "0kbh835p7dl4h88qv55fyfh1za09cgnqh63rii325w9215hm95x8"))))
+                "142qcgs8dwnzhymn0a7xx47p9fc2z5wrb86ah4a9iz0mpqlsz288"))))
     (build-system gnu-build-system)
     (arguments
      '(#:tests? #f ; XXX: fail to build the in-source git.
@@ -467,7 +469,7 @@ to lock down your entire repository.")
      ;; For building manpage.
      `(("asciidoc" ,asciidoc)))
     (inputs
-     `(("git:src" ,(package-source git@2.9))
+     `(("git:src" ,(package-source git@2.10))
        ("openssl" ,openssl)
        ("zlib" ,zlib)))
     (home-page "https://git.zx2c4.com/cgit/")
@@ -685,14 +687,14 @@ and offers an easy and intuitive interface.")
 (define-public neon
   (package
     (name "neon")
-    (version "0.30.1")
+    (version "0.30.2")
     (source (origin
              (method url-fetch)
              (uri (string-append "http://www.webdav.org/neon/neon-"
                                  version ".tar.gz"))
              (sha256
               (base32
-               "1pawhk02x728xn396a1kcivy9gqm94srmgad6ymr9l0qvk02dih0"))))
+               "1jpvczcx658vimqm7c8my2q41fnmjaf1j03g7bsli6rjxk6xh2yv"))))
     (build-system gnu-build-system)
     (native-inputs
      `(("perl" ,perl)
@@ -712,22 +714,25 @@ and offers an easy and intuitive interface.")
                            "--with-ssl=openssl")))
     (home-page "http://www.webdav.org/neon/")
     (synopsis "HTTP and WebDAV client library")
-    (description "Neon is an HTTP and WebDAV client library, with a
-C interface.  Features:
-High-level wrappers for common HTTP and WebDAV operations (GET, MOVE,
-DELETE, etc.);
-low-level interface to the HTTP request/response engine, allowing the use
-of arbitrary HTTP methods, headers, etc.;
-authentication support including Basic and Digest support, along with
-GSSAPI-based Negotiate on Unix, and SSPI-based Negotiate/NTLM on Win32;
-SSL/TLS support using OpenSSL or GnuTLS, exposing an abstraction layer for
-verifying server certificates, handling client certificates, and examining
-certificate properties, smartcard-based client certificates are also
-supported via a PKCS#11 wrapper interface;
-abstract interface to parsing XML using libxml2 or expat, and wrappers for
-simplifying handling XML HTTP response bodies;
-WebDAV metadata support, wrappers for PROPFIND and PROPPATCH to simplify
-property manipulation.")
+    (description
+     "Neon is an HTTP and WebDAV client library, with a C interface and the
+following features:
+@enumerate
+@item High-level wrappers for common HTTP and WebDAV operations (GET, MOVE,
+  DELETE, etc.);
+@item low-level interface to the HTTP request/response engine, allowing the use
+  of arbitrary HTTP methods, headers, etc.;
+@item authentication support including Basic and Digest support, along with
+  GSSAPI-based Negotiate on Unix, and SSPI-based Negotiate/NTLM on Win32;
+@item SSL/TLS support using OpenSSL or GnuTLS, exposing an abstraction layer for
+  verifying server certificates, handling client certificates, and examining
+  certificate properties, smartcard-based client certificates are also
+  supported via a PKCS#11 wrapper interface;
+@item abstract interface to parsing XML using libxml2 or expat, and wrappers for
+  simplifying handling XML HTTP response bodies;
+@item WebDAV metadata support, wrappers for PROPFIND and PROPPATCH to simplify
+  property manipulation.
+@end enumerate\n")
     (license license:gpl2+))) ; for documentation and tests; source under lgpl2.0+
 
 (define-public subversion
@@ -829,7 +834,7 @@ machine.")
     (source (origin
              (method url-fetch)
              (uri (string-append
-                   "http://ftp.gnu.org/non-gnu/cvs/source/feature/"
+                   "https://ftp.gnu.org/non-gnu/cvs/source/feature/"
                    version "/cvs-" version ".tar.bz2"))
              (sha256
               (base32
@@ -914,22 +919,25 @@ standards-compliant ChangeLog entries based on the changes that it detects.")
 (define-public diffstat
   (package
     (name "diffstat")
-    (version "1.58")
+    (version "1.61")
     (source (origin
               (method url-fetch)
-              (uri (string-append
-                    "ftp://invisible-island.net/diffstat/diffstat-"
-                    version ".tgz"))
+              (uri
+               (list
+                 (string-append "ftp://invisible-island.net/diffstat/"
+                                name "-" version ".tgz")
+                 (string-append "http://invisible-mirror.net/archives/diffstat/"
+                                name "-" version ".tgz")))
               (sha256
                (base32
-                "14rpf5c05ff30f6vn6pn6pzy0k4g4is5im656ahsxff3k58i7mgs"))))
+                "1vjmda2zfjxg0qkaj8hfqa8g6bfwnn1ja8696rxrjgqq4w69wd95"))))
     (build-system gnu-build-system)
     (home-page "http://invisible-island.net/diffstat/")
-    (synopsis "Make histograms from the output of 'diff'")
+    (synopsis "Make histograms from the output of @command{diff}")
     (description
-     "Diffstat reads the output of 'diff' and displays a histogram of the
-insertions, deletions, and modifications per-file.  It is useful for reviewing
-large, complex patch files.")
+     "Diffstat reads the output of @command{diff} and displays a histogram of
+the insertions, deletions, and modifications per file.  It is useful for
+reviewing large, complex patch files.")
     (license (license:x11-style "file://COPYING"))))
 
 (define-public cssc
@@ -1289,7 +1297,7 @@ a built-in wiki, built-in file browsing, built-in tickets system, etc.")
     (version "0.5")
     (source (origin
               (method url-fetch)
-              (uri (string-append "http://dl.2f30.org/releases/"
+              (uri (string-append "https://dl.2f30.org/releases/"
                                   name "-" version ".tar.gz"))
               (sha256
                (base32
@@ -1304,7 +1312,7 @@ a built-in wiki, built-in file browsing, built-in tickets system, etc.")
          (delete 'configure)))) ; No configure script
     (inputs
      `(("libgit2" ,libgit2)))
-    (home-page "http://2f30.org")
+    (home-page "https://2f30.org/")
     (synopsis "Static git page generator")
     (description "Stagit creates static pages for git repositories, the results can
 be served with a HTTP file server of your choice.")
diff --git a/gnu/packages/video.scm b/gnu/packages/video.scm
index 383e88cf9b..8f7a2384f4 100644
--- a/gnu/packages/video.scm
+++ b/gnu/packages/video.scm
@@ -457,14 +457,14 @@ standards (MPEG-2, MPEG-4 ASP/H.263, MPEG-4 AVC/H.264, and VC-1/VMW3).")
 (define-public ffmpeg
   (package
     (name "ffmpeg")
-    (version "3.2.4")
+    (version "3.3")
     (source (origin
              (method url-fetch)
              (uri (string-append "https://ffmpeg.org/releases/ffmpeg-"
                                  version ".tar.xz"))
              (sha256
               (base32
-               "0ymg1mkg1n0770gmjfqp79p5ijxq04smfrsrrxc8pjc0y0agyf3f"))))
+               "17anx7rnbi63if1ndr61836lf76dpn47n0y424hc48bj05y7z7jr"))))
     (build-system gnu-build-system)
     (inputs
      `(("fontconfig" ,fontconfig)
@@ -577,7 +577,6 @@ standards (MPEG-2, MPEG-4 ASP/H.263, MPEG-4 AVC/H.264, and VC-1/VMW3).")
          "--enable-libx265"
          "--enable-openal"
          "--enable-opengl"
-         "--enable-x11grab"
 
          "--enable-runtime-cpudetect"
 
diff --git a/gnu/packages/web.scm b/gnu/packages/web.scm
index 6be196f615..cb9912e0a2 100644
--- a/gnu/packages/web.scm
+++ b/gnu/packages/web.scm
@@ -3453,13 +3453,13 @@ LaTeX.")
 (define-public r-curl
   (package
     (name "r-curl")
-    (version "2.4")
+    (version "2.5")
     (source (origin
               (method url-fetch)
               (uri (cran-uri "curl" version))
               (sha256
                (base32
-                "0j1i24irpn4hvpcs61rzq0n19rmgmn29v48qc36csjk3r661l4pm"))))
+                "09p86i5f88gx1i7cidm1ka56g0jjkghqfam96p1jhwlh2fv6nrks"))))
     (build-system r-build-system)
     (arguments
      `(#:phases
diff --git a/gnu/packages/xorg.scm b/gnu/packages/xorg.scm
index 88181e1813..b9589dc8f3 100644
--- a/gnu/packages/xorg.scm
+++ b/gnu/packages/xorg.scm
@@ -2995,7 +2995,7 @@ supported, and the RENDER extension is not accelerated by this driver.")
 (define-public xf86-video-nouveau
   (package
     (name "xf86-video-nouveau")
-    (version "1.0.14")
+    (version "1.0.15")
     (source
      (origin
        (method url-fetch)
@@ -3005,11 +3005,11 @@ supported, and the RENDER extension is not accelerated by this driver.")
              ".tar.bz2"))
        (sha256
         (base32
-         "1h9izq510m2pvg77d0y9krc0cvvbhp2y3xlrrz6id7y47jdzkpsd"))))
+         "0k0xah72ryjwak4dc4crszxrlkmi9x1s7p3sd4la642n77yi1pmf"))))
     (build-system gnu-build-system)
     (inputs `(("xorg-server" ,xorg-server)))
     (native-inputs `(("pkg-config" ,pkg-config)))
-    (home-page "http://nouveau.freedesktop.org")
+    (home-page "https://nouveau.freedesktop.org")
     (synopsis "NVIDIA video driver for X server")
     (description
      "This package provides modern, high-quality Xorg drivers for NVIDIA
@@ -5105,13 +5105,16 @@ communicates with the user via graphical controls such as buttons and
 draggable titlebars and borders.")
     (license license:x11)))
 
-;;; This package is intended to be used when building GTK+.
+;; This package is intended to be used when building GTK+.
+;; Note: It's currently marked as "hidden" to avoid having two non-eq?
+;; packages with the same name and version.
 (define-public xorg-server-1.19.3
-  (package
-    (inherit xorg-server)
-    (name "xorg-server")
-    (version "1.19.3")
-    (source
+  (hidden-package
+   (package
+     (inherit xorg-server)
+     (name "xorg-server")
+     (version "1.19.3")
+     (source
       (origin
         (method url-fetch)
         (uri (string-append
@@ -5119,7 +5122,7 @@ draggable titlebars and borders.")
               name "-" version ".tar.bz2"))
         (sha256
          (base32
-          "162s1v901djr57gxmmk4airk8hiwcz79dqyz72972x1lw1k82yk7"))))))
+          "1fw4b2lf75nsqkiyhn95b1c2if1l3cw5a188a1szx1d8l7sbk2jg")))))))
 
 (define-public xorg-server-xwayland
   (package
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index 79ba205c54..67972bf614 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -129,6 +129,8 @@
             guix-publish-configuration-host
             guix-publish-configuration-compression-level
             guix-publish-configuration-nar-path
+            guix-publish-configuration-cache
+            guix-publish-configuration-ttl
             guix-publish-service
             guix-publish-service-type
 
@@ -1442,14 +1444,21 @@ failed to register hydra.gnu.org public key: ~a~%" status))))))))
            (default 80))
   (host    guix-publish-configuration-host        ;string
            (default "localhost"))
-  (compression-level guix-publish-compression-level ;integer
+  (compression-level guix-publish-configuration-compression-level ;integer
                      (default 3))
-  (nar-path    guix-publish-nar-path              ;string
-               (default "nar")))
+  (nar-path    guix-publish-configuration-nar-path ;string
+               (default "nar"))
+  (cache       guix-publish-configuration-cache   ;#f | string
+               (default #f))
+  (workers     guix-publish-configuration-workers ;#f | integer
+               (default #f))
+  (ttl         guix-publish-configuration-ttl     ;#f | integer
+               (default #f)))
 
 (define guix-publish-shepherd-service
   (match-lambda
-    (($ <guix-publish-configuration> guix port host compression nar-path)
+    (($ <guix-publish-configuration> guix port host compression
+                                     nar-path cache workers ttl)
      (list (shepherd-service
             (provision '(guix-publish))
             (requirement '(guix-daemon))
@@ -1459,7 +1468,20 @@ failed to register hydra.gnu.org public key: ~a~%" status))))))))
                             "-p" #$(number->string port)
                             "-C" #$(number->string compression)
                             (string-append "--nar-path=" #$nar-path)
-                            (string-append "--listen=" #$host))))
+                            (string-append "--listen=" #$host)
+                            #$@(if workers
+                                   #~((string-append "--workers="
+                                                     #$(number->string
+                                                        workers)))
+                                   #~())
+                            #$@(if ttl
+                                   #~((string-append "--ttl="
+                                                     #$(number->string ttl)
+                                                     "s"))
+                                   #~())
+                            #$@(if cache
+                                   #~((string-append "--cache=" #$cache))
+                                   #~()))))
             (stop #~(make-kill-destructor)))))))
 
 (define %guix-publish-accounts
@@ -1472,13 +1494,29 @@ failed to register hydra.gnu.org public key: ~a~%" status))))))))
          (home-directory "/var/empty")
          (shell (file-append shadow "/sbin/nologin")))))
 
+(define (guix-publish-activation config)
+  (let ((cache (guix-publish-configuration-cache config)))
+    (if cache
+        (with-imported-modules '((guix build utils))
+          #~(begin
+              (use-modules (guix build utils))
+
+              (mkdir-p #$cache)
+              (let* ((pw  (getpw "guix-publish"))
+                     (uid (passwd:uid pw))
+                     (gid (passwd:gid pw)))
+                (chown #$cache uid gid))))
+        #t)))
+
 (define guix-publish-service-type
   (service-type (name 'guix-publish)
                 (extensions
                  (list (service-extension shepherd-root-service-type
                                           guix-publish-shepherd-service)
                        (service-extension account-service-type
-                                          (const %guix-publish-accounts))))
+                                          (const %guix-publish-accounts))
+                       (service-extension activation-service-type
+                                          guix-publish-activation)))
                 (default-value (guix-publish-configuration))))
 
 (define* (guix-publish-service #:key (guix guix) (port 80) (host "localhost"))
diff --git a/gnu/services/mail.scm b/gnu/services/mail.scm
index 20043d7518..6305f06f85 100644
--- a/gnu/services/mail.scm
+++ b/gnu/services/mail.scm
@@ -35,6 +35,7 @@
   #:use-module (guix gexp)
   #:use-module (ice-9 match)
   #:use-module (ice-9 format)
+  #:use-module (srfi srfi-1)
   #:export (dovecot-service
             dovecot-service-type
             dovecot-configuration
@@ -57,6 +58,8 @@
             opensmtpd-service-type
             %default-opensmtpd-config-file
 
+            mail-aliases-service-type
+
             exim-configuration
             exim-configuration?
             exim-service-type
@@ -1662,6 +1665,31 @@ accept from local for any relay
 
 
 ;;;
+;;; mail aliases.
+;;;
+
+(define (mail-aliases-etc aliases)
+  `(("aliases" ,(plain-file "aliases"
+                            ;; Ideally we'd use a format string like
+                            ;; "~:{~a: ~{~a~^,~}\n~}", but it gives a
+                            ;; warning that I can't figure out how to fix,
+                            ;; so we'll just use string-join below instead.
+                            (format #f "~:{~a: ~a\n~}"
+                                    (map (match-lambda
+                                           ((alias addresses ...)
+                                            (list alias (string-join addresses ","))))
+                                         aliases))))))
+
+(define mail-aliases-service-type
+  (service-type
+   (name 'mail-aliases)
+   (extensions
+    (list (service-extension etc-service-type mail-aliases-etc)))
+   (compose concatenate)
+   (extend append)))
+
+
+;;;
 ;;; Exim.
 ;;;
 
@@ -1671,9 +1699,7 @@ accept from local for any relay
   (package       exim-configuration-package ;<package>
                  (default exim))
   (config-file   exim-configuration-config-file ;file-like
-                 (default #f))
-  (aliases       exim-configuration-aliases ;; list of lists
-                 (default '())))
+                 (default #f)))
 
 (define %exim-accounts
   (list (user-group
@@ -1700,7 +1726,7 @@ exim_group = exim
 
 (define exim-shepherd-service
   (match-lambda
-    (($ <exim-configuration> package config-file aliases)
+    (($ <exim-configuration> package config-file)
      (list (shepherd-service
             (provision '(exim mta))
             (documentation "Run the exim daemon.")
@@ -1713,7 +1739,7 @@ exim_group = exim
 
 (define exim-activation
   (match-lambda
-    (($ <exim-configuration> package config-file aliases)
+    (($ <exim-configuration> package config-file)
      (with-imported-modules '((guix build utils))
        #~(begin
            (use-modules (guix build utils))
@@ -1726,20 +1752,6 @@ exim_group = exim
            (zero? (system* #$(file-append package "/bin/exim")
                            "-bV" "-C" #$(exim-computed-config-file package config-file))))))))
 
-(define exim-etc
-  (match-lambda
-    (($ <exim-configuration> package config-file aliases)
-     `(("aliases" ,(plain-file "aliases"
-                               ;; Ideally we'd use a format string like
-                               ;; "~:{~a: ~{~a~^,~}\n~}", but it gives a
-                               ;; warning that I can't figure out how to fix,
-                               ;; so we'll just use string-join below instead.
-                               (format #f "~:{~a: ~a\n~}"
-                                       (map (lambda (entry)
-                                              (list (car entry)
-                                                    (string-join (cdr entry) ",")))
-                                            aliases))))))))
-
 (define exim-profile
   (compose list exim-configuration-package))
 
@@ -1751,4 +1763,4 @@ exim_group = exim
           (service-extension account-service-type (const %exim-accounts))
           (service-extension activation-service-type exim-activation)
           (service-extension profile-service-type exim-profile)
-          (service-extension etc-service-type exim-etc)))))
+          (service-extension mail-aliases-service-type (const '()))))))
diff --git a/gnu/services/web.scm b/gnu/services/web.scm
index 11408d7b0e..b7b2f67f13 100644
--- a/gnu/services/web.scm
+++ b/gnu/services/web.scm
@@ -180,7 +180,7 @@ of index files."
          (nginx-upstream-configuration-servers upstream)))
    "    }\n"))
 
-(define (default-nginx-config log-directory run-directory server-list upstream-list)
+(define (default-nginx-config nginx log-directory run-directory server-list upstream-list)
   (mixed-text-file "nginx.conf"
                "user nginx nginx;\n"
                "pid " run-directory "/pid;\n"
@@ -192,6 +192,7 @@ of index files."
                "    uwsgi_temp_path " run-directory "/uwsgi_temp;\n"
                "    scgi_temp_path " run-directory "/scgi_temp;\n"
                "    access_log " log-directory "/access.log;\n"
+               "    include " nginx "/share/nginx/conf/mime.types;\n"
                "\n"
                (string-join
                 (filter (lambda (section) (not (null? section)))
@@ -235,7 +236,7 @@ of index files."
          ;; Check configuration file syntax.
          (system* (string-append #$nginx "/sbin/nginx")
                   "-c" #$(or config-file
-                             (default-nginx-config log-directory
+                             (default-nginx-config nginx log-directory
                                run-directory server-blocks upstream-blocks))
                   "-t")))))
 
@@ -250,7 +251,7 @@ of index files."
                    (zero?
                     (system* #$nginx-binary "-c"
                              #$(or config-file
-                                   (default-nginx-config log-directory
+                                   (default-nginx-config nginx log-directory
                                      run-directory server-blocks upstream-blocks))
                              #$@args))))))
 
diff --git a/gnu/system.scm b/gnu/system.scm
index 89c4150f99..44190bdfc6 100644
--- a/gnu/system.scm
+++ b/gnu/system.scm
@@ -73,7 +73,7 @@
             operating-system-hosts-file
             operating-system-kernel
             operating-system-kernel-file
-            operating-system-kernel-arguments
+            operating-system-user-kernel-arguments
             operating-system-initrd
             operating-system-users
             operating-system-groups
@@ -129,7 +129,7 @@
   operating-system?
   (kernel operating-system-kernel                 ; package
           (default linux-libre))
-  (kernel-arguments operating-system-kernel-arguments
+  (kernel-arguments operating-system-user-kernel-arguments
                     (default '()))                ; list of gexps/strings
   (bootloader operating-system-bootloader)        ; <grub-configuration>
 
@@ -278,7 +278,7 @@ value of the SYSTEM-SERVICE-TYPE service."
         (mlet %store-monad
             ((kernel  ->  (operating-system-kernel os))
              (initrd      (operating-system-initrd-file os))
-             (params      (operating-system-parameters-file os)))
+             (params      (operating-system-boot-parameters-file os)))
           (return `(("kernel" ,kernel)
                     ("parameters" ,params)
                     ("initrd" ,initrd)
@@ -385,7 +385,7 @@ explicitly appear in OS."
          ;; The packages below are also in %FINAL-INPUTS, so take them from
          ;; there to avoid duplication.
          (map canonical-package
-              (list guile-2.0 bash coreutils findutils grep sed
+              (list guile-2.0 bash coreutils-8.27 findutils grep sed
                     diffutils patch gawk tar gzip bzip2 xz lzip))))
 
 (define %default-issue
@@ -756,7 +756,7 @@ populate the \"old entries\" menu."
                                    #~(string-append "--system=" #$system)
                                    #~(string-append "--load=" #$system
                                                     "/boot")
-                                   (operating-system-kernel-arguments os)))
+                                   (operating-system-user-kernel-arguments os)))
                            (initrd initrd)))))
     (grub-configuration-file (operating-system-bootloader os) entries
                              #:old-entries old-entries)))
@@ -769,7 +769,7 @@ device in a <menu-entry>."
     ((label) (file-system-device fs))
     (else #f)))
 
-(define (operating-system-parameters-file os)
+(define (operating-system-boot-parameters-file os)
   "Return a file that describes the boot parameters of OS.  The primary use of
 this file is the reconstruction of GRUB menu entries for old configurations."
   (mlet %store-monad ((initrd   (operating-system-initrd-file os))
@@ -784,7 +784,7 @@ this file is the reconstruction of GRUB menu entries for old configurations."
                    (root-device #$(file-system-device root))
                    (kernel #$(operating-system-kernel-file os))
                    (kernel-arguments
-                    #$(operating-system-kernel-arguments os))
+                    #$(operating-system-user-kernel-arguments os))
                    (initrd #$initrd)
                    (store
                     (device #$(fs->boot-device store))
diff --git a/gnu/system/vm.scm b/gnu/system/vm.scm
index 374d8b6636..4f915c4f95 100644
--- a/gnu/system/vm.scm
+++ b/gnu/system/vm.scm
@@ -494,7 +494,7 @@ it is mostly useful when FULL-BOOT?  is true."
               (string-append "--system=" #$os-drv)
               (string-append "--load=" #$os-drv "/boot")
               #$@(if graphic? #~() #~("console=ttyS0"))
-              #+@(operating-system-kernel-arguments os)))
+              #+@(operating-system-user-kernel-arguments os)))
 
     (define qemu-exec
       #~(list (string-append #$qemu "/bin/" #$(qemu-command (%current-system)))
diff --git a/gnu/tests/mail.scm b/gnu/tests/mail.scm
index d5c08b7f09..247f4f667f 100644
--- a/gnu/tests/mail.scm
+++ b/gnu/tests/mail.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2016 Sou Bunnbu <iyzsong@member.fsf.org>
+;;; Copyright © 2017 Carlo Zancanaro <carlo@zancanaro.id.au>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -26,7 +27,9 @@
   #:use-module (guix gexp)
   #:use-module (guix monads)
   #:use-module (guix store)
-  #:export (%test-opensmtpd))
+  #:use-module (ice-9 ftw)
+  #:export (%test-opensmtpd
+            %test-exim))
 
 (define %opensmtpd-os
   (simple-operating-system
@@ -146,3 +149,133 @@ accept from any for local deliver to mbox
    (name "opensmtpd")
    (description "Send an email to a running OpenSMTPD server.")
    (value (run-opensmtpd-test))))
+
+
+(define %exim-os
+  (simple-operating-system
+   (dhcp-client-service)
+   (service mail-aliases-service-type '())
+   (service exim-service-type
+            (exim-configuration
+             (config-file
+              (plain-file "exim.conf" "
+primary_hostname = komputilo
+domainlist local_domains = @
+domainlist relay_to_domains =
+hostlist   relay_from_hosts = localhost
+
+never_users =
+
+acl_smtp_rcpt = acl_check_rcpt
+acl_smtp_data = acl_check_data
+
+begin acl
+
+acl_check_rcpt:
+  accept
+acl_check_data:
+  accept
+"))))))
+
+(define (run-exim-test)
+  "Return a test of an OS running an Exim service."
+  (mlet* %store-monad ((command (system-qemu-image/shared-store-script
+                                 (marionette-operating-system
+                                  %exim-os
+                                  #:imported-modules '((gnu services herd)))
+                                 #:graphic? #f)))
+    (define test
+      (with-imported-modules '((gnu build marionette)
+                               (ice-9 ftw))
+        #~(begin
+            (use-modules (rnrs base)
+                         (srfi srfi-64)
+                         (ice-9 ftw)
+                         (ice-9 rdelim)
+                         (ice-9 regex)
+                         (gnu build marionette))
+
+            (define marionette
+              (make-marionette
+               ;; Enable TCP forwarding of the guest's port 25.
+               '(#$command "-net" "user,hostfwd=tcp::1025-:25")))
+
+            (define (read-reply-code port)
+              "Read a SMTP reply from PORT and return its reply code."
+              (let* ((line      (read-line port))
+                     (mo        (string-match "([0-9]+)([ -]).*" line))
+                     (code      (string->number (match:substring mo 1)))
+                     (finished? (string= " " (match:substring mo 2))))
+                (if finished?
+                    code
+                    (read-reply-code port))))
+
+            (define smtp (socket AF_INET SOCK_STREAM 0))
+            (define addr (make-socket-address AF_INET INADDR_LOOPBACK 1025))
+
+            (mkdir #$output)
+            (chdir #$output)
+
+            (test-begin "exim")
+
+            (test-assert "service is running"
+              (marionette-eval
+               '(begin
+                  (use-modules (gnu services herd))
+                  (start-service 'exim)
+                  #t)
+               marionette))
+
+            (sleep 1) ;; give the service time to start talking
+
+            (connect smtp addr)
+            ;; Be greeted.
+            (test-eq "greeting received"
+              220 (read-reply-code smtp))
+            ;; Greet the server.
+            (write-line "EHLO somehost" smtp)
+            (test-eq "greeting successful"
+              250 (read-reply-code smtp))
+            ;; Set sender email.
+            (write-line "MAIL FROM: test@example.com" smtp)
+            (test-eq "sender set"
+              250 (read-reply-code smtp)) ;250
+            ;; Set recipient email.
+            (write-line "RCPT TO: root@komputilo" smtp)
+            (test-eq "recipient set"
+              250 (read-reply-code smtp)) ;250
+            ;; Send message.
+            (write-line "DATA" smtp)
+            (test-eq "data begun"
+              354 (read-reply-code smtp)) ;354
+            (write-line "Subject: Hello" smtp)
+            (newline smtp)
+            (write-line "Nice to meet you!" smtp)
+            (write-line "." smtp)
+            (test-eq "message sent"
+              250 (read-reply-code smtp)) ;250
+            ;; Say goodbye.
+            (write-line "QUIT" smtp)
+            (test-eq "quit successful"
+              221 (read-reply-code smtp)) ;221
+            (close smtp)
+
+            (test-eq "the email is received"
+              1
+              (marionette-eval
+               '(begin
+                  (use-modules (ice-9 ftw))
+                  (length (scandir "/var/spool/exim/msglog"
+                                   (lambda (x) (not (string-prefix? "." x))))))
+               marionette))
+
+            (test-end)
+            (exit (= (test-runner-fail-count (test-runner-current)) 0)))))
+
+    (gexp->derivation "exim-test" test)))
+
+(define %test-exim
+  (system-test
+   (name "exim")
+   (description "Send an email to a running an Exim server.")
+   (value (run-exim-test))))
diff --git a/guix/build/download.scm b/guix/build/download.scm
index e3d5244590..67a8952599 100644
--- a/guix/build/download.scm
+++ b/guix/build/download.scm
@@ -140,6 +140,13 @@ Otherwise return STORE-PATH."
                        (string-drop base 32)))
       store-path))
 
+(cond-expand
+  (guile-2.2
+   ;; Guile 2.2.2 has a bug whereby 'time-monotonic' objects have seconds and
+   ;; nanoseconds swapped (fixed in Guile commit 886ac3e).  Work around it.
+   (define time-monotonic time-tai))
+  (else #t))
+
 (define* (progress-proc file size
                         #:optional (log-port (current-output-port))
                         #:key (abbreviation basename))
diff --git a/guix/cache.scm b/guix/cache.scm
new file mode 100644
index 0000000000..1dc0083f1d
--- /dev/null
+++ b/guix/cache.scm
@@ -0,0 +1,113 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix cache)
+  #:use-module (srfi srfi-19)
+  #:use-module (srfi srfi-26)
+  #:use-module (ice-9 match)
+  #:export (obsolete?
+            delete-file*
+            file-expiration-time
+            remove-expired-cache-entries
+            maybe-remove-expired-cache-entries))
+
+;;; Commentary:
+;;;
+;;; This module provides tools to manage a simple on-disk cache consisting of
+;;; individual files.
+;;;
+;;; Code:
+
+(cond-expand
+  (guile-2.2
+   ;; Guile 2.2.2 has a bug whereby 'time-monotonic' objects have seconds and
+   ;; nanoseconds swapped (fixed in Guile commit 886ac3e).  Work around it.
+   (define time-monotonic time-tai))
+  (else #t))
+
+(define (obsolete? date now ttl)
+  "Return #t if DATE is obsolete compared to NOW + TTL seconds."
+  (time>? (subtract-duration now (make-time time-duration 0 ttl))
+          (make-time time-monotonic 0 date)))
+
+(define (delete-file* file)
+  "Like 'delete-file', but does not raise an error when FILE does not exist."
+  (catch 'system-error
+    (lambda ()
+      (delete-file file))
+    (lambda args
+      (unless (= ENOENT (system-error-errno args))
+        (apply throw args)))))
+
+(define (file-expiration-time ttl)
+  "Return a procedure that, when passed a file, returns its \"expiration
+time\" computed as its last-access time + TTL seconds."
+  (lambda (file)
+    (match (stat file #f)
+      (#f 0)                       ;FILE may have been deleted in the meantime
+      (st (+ (stat:atime st) ttl)))))
+
+(define* (remove-expired-cache-entries entries
+                                       #:key
+                                       (now (current-time time-monotonic))
+                                       (entry-expiration
+                                        (file-expiration-time 3600))
+                                       (delete-entry delete-file*))
+  "Given ENTRIES, a list of file names, remove those whose expiration time,
+as returned by ENTRY-EXPIRATION, has passed.  Use DELETE-ENTRY to delete
+them."
+  (for-each (lambda (entry)
+              (when (<= (entry-expiration entry) (time-second now))
+                (delete-entry entry)))
+            entries))
+
+(define* (maybe-remove-expired-cache-entries cache
+                                             cache-entries
+                                             #:key
+                                             (entry-expiration
+                                              (file-expiration-time 3600))
+                                             (delete-entry delete-file*)
+                                             (cleanup-period (* 24 3600)))
+  "Remove expired narinfo entries from the cache if deemed necessary.  Call
+CACHE-ENTRIES with CACHE to retrieve the list of cache entries.
+
+ENTRY-EXPIRATION must be a procedure that, when passed an entry, returns the
+expiration time of that entry in seconds since the Epoch.  DELETE-ENTRY is a
+procedure that removes the entry passed as an argument.  Finally,
+CLEANUP-PERIOD denotes the minimum time between two cache cleanups."
+  (define now
+    (current-time time-monotonic))
+
+  (define expiry-file
+    (string-append cache "/last-expiry-cleanup"))
+
+  (define last-expiry-date
+    (catch 'system-error
+      (lambda ()
+        (call-with-input-file expiry-file read))
+      (const 0)))
+
+  (when (obsolete? last-expiry-date now cleanup-period)
+    (remove-expired-cache-entries (cache-entries cache)
+                                  #:now now
+                                  #:entry-expiration entry-expiration
+                                  #:delete-entry delete-entry)
+    (call-with-output-file expiry-file
+      (cute write (time-second now) <>))))
+
+;;; cache.scm ends here
diff --git a/guix/derivations.scm b/guix/derivations.scm
index 0846d54fa5..d5e0f453e2 100644
--- a/guix/derivations.scm
+++ b/guix/derivations.scm
@@ -566,12 +566,14 @@ that form."
      (write-list env-vars write-env-var port)
      (display ")" port))))
 
-(define derivation->string
+(define derivation->bytevector
   (mlambda (drv)
-    "Return the external representation of DRV as a string."
+    "Return the external representation of DRV as a UTF-8-encoded string."
     (with-fluids ((%default-port-encoding "UTF-8"))
-      (call-with-output-string
-        (cut write-derivation drv <>)))))
+      (call-with-values open-bytevector-output-port
+        (lambda (port get-bytevector)
+          (write-derivation drv port)
+          (get-bytevector))))))
 
 (define* (derivation->output-path drv #:optional (output "out"))
   "Return the store path of its output OUTPUT.  Raise a
@@ -670,8 +672,7 @@ derivation at FILE."
          ;; XXX: At this point this remains faster than `port-sha256', because
          ;; the SHA256 port's `write' method gets called for every single
          ;; character.
-         (sha256
-          (string->utf8 (derivation->string drv))))))))
+         (sha256 (derivation->bytevector drv)))))))
 
 (define (store-path type hash name)               ; makeStorePath
   "Return the store path for NAME/HASH/TYPE."
@@ -872,8 +873,8 @@ output should not be used."
                                       system builder args env-vars #f))
          (drv        (add-output-paths drv-masked)))
 
-    (let* ((file (add-text-to-store store (string-append name ".drv")
-                                    (derivation->string drv)
+    (let* ((file (add-data-to-store store (string-append name ".drv")
+                                    (derivation->bytevector drv)
                                     (map derivation-input-path inputs)))
            (drv* (set-field drv (derivation-file-name) file)))
       (hash-set! %derivation-cache file drv*)
@@ -1245,15 +1246,15 @@ ALLOWED-REFERENCES, DISALLOWED-REFERENCES, LOCAL-BUILD?, and SUBSTITUTABLE?."
                                       (with-fluids ((%default-port-encoding
                                                      "UTF-8"))
                                         (call-with-output-string
-                                         (lambda (port)
-                                           (write prologue port)
-                                           (write
-                                            `(exit
-                                              ,(match exp
-                                                 ((_ ...)
-                                                  (remove module-form? exp))
-                                                 (_ `(,exp))))
-                                            port))))
+                                          (lambda (port)
+                                            (write prologue port)
+                                            (write
+                                             `(exit
+                                               ,(match exp
+                                                  ((_ ...)
+                                                   (remove module-form? exp))
+                                                  (_ `(,exp))))
+                                             port))))
 
                                       ;; The references don't really matter
                                       ;; since the builder is always used in
diff --git a/guix/gexp.scm b/guix/gexp.scm
index 80d8f735b3..d9c4cb461e 100644
--- a/guix/gexp.scm
+++ b/guix/gexp.scm
@@ -459,21 +459,24 @@ whether this should be considered a \"native\" input or not."
 (set-record-type-printer! <gexp-output> write-gexp-output)
 
 (define (gexp-modules gexp)
-  "Return the list of Guile module names GEXP relies on."
-  (delete-duplicates
-   (append (gexp-self-modules gexp)
-           (append-map (match-lambda
-                         (($ <gexp-input> (? gexp? exp))
-                          (gexp-modules exp))
-                         (($ <gexp-input> (lst ...))
-                          (append-map (lambda (item)
-                                        (if (gexp? item)
-                                            (gexp-modules item)
-                                            '()))
-                                      lst))
-                         (_
-                          '()))
-                       (gexp-references gexp)))))
+  "Return the list of Guile module names GEXP relies on.  If (gexp? GEXP) is
+false, meaning that GEXP is a plain Scheme object, return the empty list."
+  (if (gexp? gexp)
+      (delete-duplicates
+       (append (gexp-self-modules gexp)
+               (append-map (match-lambda
+                             (($ <gexp-input> (? gexp? exp))
+                              (gexp-modules exp))
+                             (($ <gexp-input> (lst ...))
+                              (append-map (lambda (item)
+                                            (if (gexp? item)
+                                                (gexp-modules item)
+                                                '()))
+                                          lst))
+                             (_
+                              '()))
+                           (gexp-references gexp))))
+      '()))                                       ;plain Scheme data type
 
 (define* (lower-inputs inputs
                        #:key system target)
diff --git a/guix/scripts/copy.scm b/guix/scripts/copy.scm
index 624ef73e96..bc225044fb 100644
--- a/guix/scripts/copy.scm
+++ b/guix/scripts/copy.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2016, 2017 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -25,9 +25,6 @@
   #:use-module (guix derivations)
   #:use-module (guix scripts build)
   #:use-module ((guix scripts archive) #:select (options->derivations+files))
-  #:use-module (ssh session)
-  #:use-module (ssh auth)
-  #:use-module (ssh key)
   #:use-module (srfi srfi-1)
   #:use-module (srfi srfi-11)
   #:use-module (srfi srfi-37)
@@ -40,42 +37,6 @@
 ;;; Exchanging store items over SSH.
 ;;;
 
-(define %compression
-  "zlib@openssh.com,zlib")
-
-(define* (open-ssh-session host #:key user port)
-  "Open an SSH session for HOST and return it.  When USER and PORT are #f, use
-default values or whatever '~/.ssh/config' specifies; otherwise use them.
-Throw an error on failure."
-  (let ((session (make-session #:user user
-                               #:host host
-                               #:port port
-                               #:timeout 10       ;seconds
-                               ;; #:log-verbosity 'protocol
-
-                               ;; We need lightweight compression when
-                               ;; exchanging full archives.
-                               #:compression %compression
-                               #:compression-level 3)))
-
-    ;; Honor ~/.ssh/config.
-    (session-parse-config! session)
-
-    (match (connect! session)
-      ('ok
-       ;; Use public key authentication, via the SSH agent if it's available.
-       (match (userauth-public-key/auto! session)
-         ('success
-          session)
-         (x
-          (disconnect! session)
-          (leave (_ "SSH authentication failed for '~a': ~a~%")
-                 host (get-error session)))))
-      (x
-       ;; Connection failed or timeout expired.
-       (leave (_ "SSH connection to '~a' failed: ~a~%")
-              host (get-error session))))))
-
 (define (ssh-spec->user+host+port spec)
   "Parse SPEC, a string like \"user@host:port\" or just \"host\", and return
 three values: the user name (or #f), the host name, and the TCP port
diff --git a/guix/scripts/offload.scm b/guix/scripts/offload.scm
index 6a4ae28689..acdfb81698 100644
--- a/guix/scripts/offload.scm
+++ b/guix/scripts/offload.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -148,7 +148,7 @@ its key type as a symbol, and the actual base64-encoded string."
          (string->symbol (string-drop type 4))))
 
   (match (string-tokenize host-key)
-    ((type key _)
+    ((type key x)
      (values (type->symbol type) key))
     ((type key)
      (values (type->symbol type) key))))
@@ -403,7 +403,7 @@ allowed on MACHINE.  Return +∞ if MACHINE is unreachable."
        (if (eof-object? line)
            +inf.0 ;MACHINE does not respond, so assume it is infinitely loaded
            (match (string-tokenize line)
-             ((one five fifteen . _)
+             ((one five fifteen . x)
               (let* ((raw        (string->number five))
                      (jobs       (build-machine-parallel-builds machine))
                      (normalized (/ raw jobs)))
@@ -411,9 +411,9 @@ allowed on MACHINE.  Return +∞ if MACHINE is unreachable."
  (normalized: ~s)~%"
                         (build-machine-name machine) raw normalized)
                 normalized))
-             (_
+             (x
               +inf.0)))))        ;something's fishy about MACHINE, so avoid it
-    (_
+    (x
      +inf.0)))                      ;failed to connect to MACHINE, so avoid it
 
 (define (machine-lock-file machine hint)
@@ -503,7 +503,7 @@ allowed on MACHINE.  Return +∞ if MACHINE is unreachable."
       (()
        ;; We'll never be able to match REQS.
        (display "# decline\n"))
-      ((_ ...)
+      ((x ...)
        (let ((machine (choose-build-machine candidates)))
          (if machine
              (begin
@@ -671,7 +671,7 @@ machine."
                                          build-machine-name)))
                        ((file) (values file (const #t)))
                        (()     (values %machine-file (const #t)))
-                       (_      (leave (_ "wrong number of arguments~%"))))))
+                       (x      (leave (_ "wrong number of arguments~%"))))))
          (check-machine-availability (or file %machine-file) pred))))
     (("--version")
      (show-version-and-exit "guix offload"))
diff --git a/guix/scripts/publish.scm b/guix/scripts/publish.scm
index d8ac72f4ef..3faff061a7 100644
--- a/guix/scripts/publish.scm
+++ b/guix/scripts/publish.scm
@@ -24,6 +24,7 @@
   #:use-module (ice-9 match)
   #:use-module (ice-9 regex)
   #:use-module (ice-9 rdelim)
+  #:use-module (ice-9 threads)
   #:use-module (rnrs bytevectors)
   #:use-module (srfi srfi-1)
   #:use-module (srfi srfi-2)
@@ -38,6 +39,7 @@
   #:use-module (web response)
   #:use-module (web server)
   #:use-module (web uri)
+  #:autoload   (sxml simple) (sxml->xml)
   #:use-module (guix base32)
   #:use-module (guix base64)
   #:use-module (guix config)
@@ -45,13 +47,17 @@
   #:use-module (guix hash)
   #:use-module (guix pki)
   #:use-module (guix pk-crypto)
+  #:use-module (guix workers)
   #:use-module (guix store)
   #:use-module ((guix serialization) #:select (write-file))
   #:use-module (guix zlib)
+  #:use-module (guix cache)
   #:use-module (guix ui)
   #:use-module (guix scripts)
-  #:use-module ((guix utils) #:select (compressed-file?))
-  #:use-module ((guix build utils) #:select (dump-port))
+  #:use-module ((guix utils)
+                #:select (with-atomic-file-output compressed-file?))
+  #:use-module ((guix build utils)
+                #:select (dump-port mkdir-p find-files))
   #:export (%public-key
             %private-key
 
@@ -70,6 +76,10 @@ Publish ~a over HTTP.\n") %store-directory)
   -C, --compression[=LEVEL]
                          compress archives at LEVEL"))
   (display (_ "
+  -c, --cache=DIRECTORY  cache published items to DIRECTORY"))
+  (display (_ "
+      --workers=N        use N workers to bake items"))
+  (display (_ "
       --ttl=TTL          announce narinfos can be cached for TTL seconds"))
   (display (_ "
       --nar-path=PATH    use PATH as the prefix for nar URLs"))
@@ -110,6 +120,13 @@ Publish ~a over HTTP.\n") %store-directory)
   ;; Since we compress on the fly, default to fast compression.
   (compression 'gzip 3))
 
+(define (actual-compression item requested)
+  "Return the actual compression used for ITEM, which may be %NO-COMPRESSION
+if ITEM is already compressed."
+  (if (compressed-file? item)
+      %no-compression
+      requested))
+
 (define %options
   (list (option '(#\h "help") #f #f
                 (lambda _
@@ -147,6 +164,13 @@ Publish ~a over HTTP.\n") %store-directory)
                            (warning (_ "zlib support is missing; \
 compression disabled~%"))
                            result))))))
+        (option '(#\c "cache") #t #f
+                (lambda (opt name arg result)
+                  (alist-cons 'cache arg result)))
+        (option '("workers") #t #f
+                (lambda (opt name arg result)
+                  (alist-cons 'workers (string->number* arg)
+                              result)))
         (option '("ttl") #t #f
                 (lambda (opt name arg result)
                   (let ((duration (string->duration arg)))
@@ -183,6 +207,9 @@ compression disabled~%"))
                         %default-gzip-compression
                         %no-compression))
 
+    ;; Default number of workers when caching is enabled.
+    (workers . ,(current-processor-count))
+
     (address . ,(make-socket-address AF_INET INADDR_ANY 0))
     (repl . #f)))
 
@@ -218,9 +245,7 @@ compression disabled~%"))
 if STORE-PATH is invalid.  Produce a URL that corresponds to COMPRESSION.  The
 narinfo is signed with KEY.  NAR-PATH specifies the prefix for nar URLs."
   (let* ((path-info  (query-path-info store store-path))
-         (compression (if (compressed-file? store-path)
-                          %no-compression
-                          compression))
+         (compression (actual-compression store-path compression))
          (url        (encode-and-join-uri-path
                       `(,@(split-and-decode-uri-path nar-path)
                         ,@(match compression
@@ -303,6 +328,146 @@ appropriate duration.  NAR-PATH specifies the prefix for nar URLs."
                                   #:compression compression)
                   <>)))))
 
+(define* (nar-cache-file directory item
+                             #:key (compression %no-compression))
+  (string-append directory "/"
+                 (symbol->string (compression-type compression))
+                 "/" (basename item) ".nar"))
+
+(define* (narinfo-cache-file directory item
+                             #:key (compression %no-compression))
+  (string-append directory "/"
+                 (symbol->string (compression-type compression))
+                 "/" (basename item)
+                 ".narinfo"))
+
+(define run-single-baker
+  (let ((baking (make-weak-value-hash-table))
+        (mutex  (make-mutex)))
+    (lambda (item thunk)
+      "Run THUNK, which is supposed to bake ITEM, but make sure only one
+thread is baking ITEM at a given time."
+      (define selected?
+        (with-mutex mutex
+          (and (not (hash-ref baking item))
+               (begin
+                 (hash-set! baking item (current-thread))
+                 #t))))
+
+      (when selected?
+        (dynamic-wind
+          (const #t)
+          thunk
+          (lambda ()
+            (with-mutex mutex
+              (hash-remove! baking item))))))))
+
+(define-syntax-rule (single-baker item exp ...)
+  "Bake ITEM by evaluating EXP, but make sure there's only one baker for ITEM
+at a time."
+  (run-single-baker item (lambda () exp ...)))
+
+
+(define (narinfo-files cache)
+  "Return the list of .narinfo files under CACHE."
+  (if (file-is-directory? cache)
+      (find-files cache
+                  (lambda (file stat)
+                    (string-suffix? ".narinfo" file)))
+      '()))
+
+(define* (render-narinfo/cached store request hash
+                                #:key ttl (compression %no-compression)
+                                (nar-path "nar")
+                                cache pool)
+  "Respond to the narinfo request for REQUEST.  If the narinfo is available in
+CACHE, then send it; otherwise, return 404 and \"bake\" that nar and narinfo
+requested using POOL."
+  (define (delete-entry narinfo)
+    ;; Delete NARINFO and the corresponding nar from CACHE.
+    (let ((nar (string-append (string-drop-right narinfo
+                                                 (string-length ".narinfo"))
+                              ".nar")))
+      (delete-file* narinfo)
+      (delete-file* nar)))
+
+  (let* ((item        (hash-part->path store hash))
+         (compression (actual-compression item compression))
+         (cached      (and (not (string-null? item))
+                           (narinfo-cache-file cache item
+                                               #:compression compression))))
+    (cond ((string-null? item)
+           (not-found request))
+          ((file-exists? cached)
+           ;; Narinfo is in cache, send it.
+           (values `((content-type . (application/x-nix-narinfo))
+                     ,@(if ttl
+                           `((cache-control (max-age . ,ttl)))
+                           '()))
+                   (lambda (port)
+                     (display (call-with-input-file cached
+                                read-string)
+                              port))))
+          ((valid-path? store item)
+           ;; Nothing in cache: bake the narinfo and nar in the background and
+           ;; return 404.
+           (eventually pool
+             (single-baker item
+               ;; (format #t "baking ~s~%" item)
+               (bake-narinfo+nar cache item
+                                 #:ttl ttl
+                                 #:compression compression
+                                 #:nar-path nar-path))
+
+             (when ttl
+               (single-baker 'cache-cleanup
+                 (maybe-remove-expired-cache-entries cache
+                                                     narinfo-files
+                                                     #:entry-expiration
+                                                     (file-expiration-time ttl)
+                                                     #:delete-entry delete-entry
+                                                     #:cleanup-period ttl))))
+           (not-found request))
+          (else
+           (not-found request)))))
+
+(define* (bake-narinfo+nar cache item
+                           #:key ttl (compression %no-compression)
+                           (nar-path "/nar"))
+  "Write the narinfo and nar for ITEM to CACHE."
+  (let* ((compression (actual-compression item compression))
+         (nar         (nar-cache-file cache item
+                                      #:compression compression))
+         (narinfo     (narinfo-cache-file cache item
+                                          #:compression compression)))
+
+    (mkdir-p (dirname nar))
+    (match (compression-type compression)
+      ('gzip
+       ;; Note: the file port gets closed along with the gzip port.
+       (call-with-gzip-output-port (open-output-file (string-append nar ".tmp"))
+         (lambda (port)
+           (write-file item port))
+         #:level (compression-level compression))
+       (rename-file (string-append nar ".tmp") nar))
+      ('none
+       ;; When compression is disabled, we retrieve files directly from the
+       ;; store; no need to cache them.
+       #t))
+
+    (mkdir-p (dirname narinfo))
+    (with-atomic-file-output narinfo
+      (lambda (port)
+        ;; Open a new connection to the store.  We cannot reuse the main
+        ;; thread's connection to the store since we would end up sending
+        ;; stuff concurrently on the same channel.
+        (with-store store
+          (display (narinfo-string store item
+                                   (%private-key)
+                                   #:nar-path nar-path
+                                   #:compression compression)
+                   port))))))
+
 ;; XXX: Declare the 'Guix-Compression' HTTP header, which is in fact for
 ;; internal consumption: it allows us to pass the compression info to
 ;; 'http-write', as part of the workaround to <http://bugs.gnu.org/21093>.
@@ -334,6 +499,21 @@ appropriate duration.  NAR-PATH specifies the prefix for nar URLs."
                 store-path)
         (not-found request))))
 
+(define* (render-nar/cached store cache request store-item
+                            #:key (compression %no-compression))
+  "Respond to REQUEST with a nar for STORE-ITEM.  If the nar is in CACHE,
+return it; otherwise, return 404."
+  (let ((cached (nar-cache-file cache store-item
+                                #:compression compression)))
+    (if (file-exists? cached)
+        (values `((content-type . (application/octet-stream
+                                   (charset . "ISO-8859-1"))))
+                ;; XXX: We're not returning the actual contents, deferring
+                ;; instead to 'http-write'.  This is a hack to work around
+                ;; <http://bugs.gnu.org/21093>.
+                cached)
+        (not-found request))))
+
 (define (render-content-addressed-file store request
                                        name algo hash)
   "Return the content of the result of the fixed-output derivation NAME that
@@ -353,6 +533,22 @@ has the given HASH of type ALGO."
             (not-found request)))
       (not-found request)))
 
+(define (render-home-page request)
+  "Render the home page."
+  (values `((content-type . (text/html (charset . "UTF-8"))))
+          (call-with-output-string
+            (lambda (port)
+              (sxml->xml '(html
+                           (head (title "GNU Guix Substitute Server"))
+                           (body
+                            (h1 "GNU Guix Substitute Server")
+                            (p "Hi, "
+                               (a (@ (href
+                                      "https://gnu.org/s/guix/manual/html_node/Invoking-guix-publish.html"))
+                                  (tt "guix publish"))
+                               " speaking.  Welcome!")))
+                         port)))))
+
 (define extract-narinfo-hash
   (let ((regexp (make-regexp "^([a-df-np-sv-z0-9]{32}).narinfo$")))
     (lambda (str)
@@ -464,7 +660,9 @@ blocking."
                                                                       size)
                                                  client))
                        (output   (response-port response)))
-                  (dump-port input output)
+                  (if (file-port? output)
+                      (sendfile output input size)
+                      (dump-port input output))
                   (close-port output)
                   (values)))))
           (lambda args
@@ -488,6 +686,7 @@ blocking."
 
 (define* (make-request-handler store
                                #:key
+                               cache pool
                                narinfo-ttl
                                (nar-path "nar")
                                (compression %no-compression))
@@ -504,14 +703,24 @@ blocking."
           ;; /nix-cache-info
           (("nix-cache-info")
            (render-nix-cache-info))
+          ;; /
+          ((or () ("index.html"))
+           (render-home-page request))
           ;; /<hash>.narinfo
           (((= extract-narinfo-hash (? string? hash)))
            ;; TODO: Register roots for HASH that will somehow remain for
            ;; NARINFO-TTL.
-           (render-narinfo store request hash
-                           #:ttl narinfo-ttl
-                           #:nar-path nar-path
-                           #:compression compression))
+           (if cache
+               (render-narinfo/cached store request hash
+                                      #:cache cache
+                                      #:pool pool
+                                      #:ttl narinfo-ttl
+                                      #:nar-path nar-path
+                                      #:compression compression)
+               (render-narinfo store request hash
+                               #:ttl narinfo-ttl
+                               #:nar-path nar-path
+                               #:compression compression)))
           ;; /nar/file/NAME/sha256/HASH
           (("file" name "sha256" hash)
            (guard (c ((invalid-base32-character? c)
@@ -527,13 +736,16 @@ blocking."
           ;; /nar/gzip/<store-item>
           ((components ... "gzip" store-item)
            (if (and (nar-path? components) (zlib-available?))
-               (render-nar store request store-item
-                           #:compression
-                           (match compression
-                             (($ <compression> 'gzip)
-                              compression)
-                             (_
-                              %default-gzip-compression)))
+               (let ((compression (match compression
+                                    (($ <compression> 'gzip)
+                                     compression)
+                                    (_
+                                     %default-gzip-compression))))
+                 (if cache
+                     (render-nar/cached store cache request store-item
+                                        #:compression compression)
+                     (render-nar store request store-item
+                                 #:compression compression)))
                (not-found request)))
 
           ;; /nar/<store-item>
@@ -548,8 +760,11 @@ blocking."
 
 (define* (run-publish-server socket store
                              #:key (compression %no-compression)
-                             (nar-path "nar") narinfo-ttl)
+                             (nar-path "nar") narinfo-ttl
+                             cache pool)
   (run-server (make-request-handler store
+                                    #:cache cache
+                                    #:pool pool
                                     #:nar-path nar-path
                                     #:narinfo-ttl narinfo-ttl
                                     #:compression compression)
@@ -599,6 +814,8 @@ blocking."
            (socket  (open-server-socket address))
            (nar-path  (assoc-ref opts 'nar-path))
            (repl-port (assoc-ref opts 'repl))
+           (cache     (assoc-ref opts 'cache))
+           (workers   (assoc-ref opts 'workers))
 
            ;; Read the key right away so that (1) we fail early on if we can't
            ;; access them, and (2) we can then drop privileges.
@@ -624,6 +841,12 @@ consider using the '--user' option!~%")))
           (repl:spawn-server (repl:make-tcp-server-socket #:port repl-port)))
         (with-store store
           (run-publish-server socket store
+                              #:cache cache
+                              #:pool (and cache (make-pool workers))
                               #:nar-path nar-path
                               #:compression compression
                               #:narinfo-ttl ttl))))))
+
+;;; Local Variables:
+;;; eval: (put 'single-baker 'scheme-indent-function 1)
+;;; End:
diff --git a/guix/scripts/substitute.scm b/guix/scripts/substitute.scm
index d3bccf4ddb..748c334e3c 100755
--- a/guix/scripts/substitute.scm
+++ b/guix/scripts/substitute.scm
@@ -28,6 +28,7 @@
   #:use-module (guix hash)
   #:use-module (guix base32)
   #:use-module (guix base64)
+  #:use-module (guix cache)
   #:use-module (guix pk-crypto)
   #:use-module (guix pki)
   #:use-module ((guix build utils) #:select (mkdir-p dump-port))
@@ -440,12 +441,6 @@ or is signed by an unauthorized key."
 the cache STR originates form."
   (call-with-input-string str (cut read-narinfo <> cache-uri)))
 
-(define (obsolete? date now ttl)
-  "Return #t if DATE is obsolete compared to NOW + TTL seconds."
-  (time>? (subtract-duration now (make-time time-duration 0 ttl))
-          (make-time time-monotonic 0 date)))
-
-
 (define (narinfo-cache-file cache-url path)
   "Return the name of the local file that contains an entry for PATH.  The
 entry is stored in a sub-directory specific to CACHE-URL."
@@ -718,43 +713,28 @@ was found."
     ((answer) answer)
     (_        #f)))
 
-(define (remove-expired-cached-narinfos directory)
-  "Remove expired narinfo entries from DIRECTORY.  The sole purpose of this
-function is to make sure `%narinfo-cache-directory' doesn't grow
-indefinitely."
-  (define now
-    (current-time time-monotonic))
+(define (cached-narinfo-expiration-time file)
+  "Return the expiration time for FILE, which is a cached narinfo."
+  (catch 'system-error
+    (lambda ()
+      (call-with-input-file file
+        (lambda (port)
+          (match (read port)
+            (('narinfo ('version 2) ('cache-uri uri)
+                       ('date date) ('ttl ttl) ('value #f))
+             (+ date %narinfo-negative-ttl))
+            (('narinfo ('version 2) ('cache-uri uri)
+                       ('date date) ('ttl ttl) ('value value))
+             (+ date ttl))
+            (x
+             0)))))
+    (lambda args
+      ;; FILE may have been deleted.
+      0)))
 
-  (define (expired? file)
-    (catch 'system-error
-      (lambda ()
-        (call-with-input-file file
-          (lambda (port)
-            (match (read port)
-              (('narinfo ('version 2) ('cache-uri _)
-                         ('date date) ('ttl _) ('value #f))
-               (obsolete? date now %narinfo-negative-ttl))
-              (('narinfo ('version 2) ('cache-uri _)
-                         ('date date) ('ttl ttl) ('value _))
-               (obsolete? date now ttl))
-              (_ #t)))))
-      (lambda args
-        ;; FILE may have been deleted.
-        #t)))
-
-  (for-each (lambda (file)
-              (let ((file (string-append directory "/" file)))
-                (when (expired? file)
-                  ;; Wrap in `false-if-exception' because FILE might have been
-                  ;; deleted in the meantime (TOCTTOU).
-                  (false-if-exception (delete-file file)))))
-            (scandir directory
-                     (lambda (file)
-                       (= (string-length file) 32)))))
-
-(define (narinfo-cache-directories)
+(define (narinfo-cache-directories directory)
   "Return the list of narinfo cache directories (one per cache URL.)"
-  (map (cut string-append %narinfo-cache-directory "/" <>)
+  (map (cut string-append directory "/" <>)
        (scandir %narinfo-cache-directory
                 (lambda (item)
                   (and (not (member item '("." "..")))
@@ -762,25 +742,15 @@ indefinitely."
                         (string-append %narinfo-cache-directory
                                        "/" item)))))))
 
-(define (maybe-remove-expired-cached-narinfo)
-  "Remove expired narinfo entries from the cache if deemed necessary."
-  (define now
-    (current-time time-monotonic))
-
-  (define expiry-file
-    (string-append %narinfo-cache-directory "/last-expiry-cleanup"))
-
-  (define last-expiry-date
-    (or (false-if-exception
-         (call-with-input-file expiry-file read))
-        0))
-
-  (when (obsolete? last-expiry-date now
-                   %narinfo-expired-cache-entry-removal-delay)
-    (for-each remove-expired-cached-narinfos
-              (narinfo-cache-directories))
-    (call-with-output-file expiry-file
-      (cute write (time-second now) <>))))
+(define* (cached-narinfo-files #:optional
+                               (directory %narinfo-cache-directory))
+  "Return the list of cached narinfo files under DIRECTORY."
+  (append-map (lambda (directory)
+                (map (cut string-append directory "/" <>)
+                     (scandir directory
+                              (lambda (file)
+                                (= (string-length file) 32)))))
+              (narinfo-cache-directories directory)))
 
 (define (progress-report-port report-progress port)
   "Return a port that calls REPORT-PROGRESS every time something is read from
@@ -1013,7 +983,12 @@ default value."
 (define (guix-substitute . args)
   "Implement the build daemon's substituter protocol."
   (mkdir-p %narinfo-cache-directory)
-  (maybe-remove-expired-cached-narinfo)
+  (maybe-remove-expired-cache-entries %narinfo-cache-directory
+                                      cached-narinfo-files
+                                      #:entry-expiration
+                                      cached-narinfo-expiration-time
+                                      #:cleanup-period
+                                      %narinfo-expired-cache-entry-removal-delay)
   (check-acl-initialized)
 
   ;; Starting from commit 22144afa in Nix, we are allowed to bail out directly
diff --git a/guix/ssh.scm b/guix/ssh.scm
index 3548243839..59fd002dc7 100644
--- a/guix/ssh.scm
+++ b/guix/ssh.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2016, 2017 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -18,7 +18,10 @@
 
 (define-module (guix ssh)
   #:use-module (guix store)
-  #:autoload   (guix ui) (N_)
+  #:use-module ((guix ui) #:select (_ N_))
+  #:use-module (ssh session)
+  #:use-module (ssh auth)
+  #:use-module (ssh key)
   #:use-module (ssh channel)
   #:use-module (ssh popen)
   #:use-module (ssh session)
@@ -29,7 +32,9 @@
   #:use-module (srfi srfi-35)
   #:use-module (ice-9 match)
   #:use-module (ice-9 binary-ports)
-  #:export (connect-to-remote-daemon
+  #:export (open-ssh-session
+            remote-daemon-channel
+            connect-to-remote-daemon
             send-files
             retrieve-files
             remote-store-host
@@ -43,11 +48,52 @@
 ;;;
 ;;; Code:
 
-(define* (connect-to-remote-daemon session
-                                   #:optional
-                                   (socket-name "/var/guix/daemon-socket/socket"))
-  "Connect to the remote build daemon listening on SOCKET-NAME over SESSION,
-an SSH session.  Return a <nix-server> object."
+(define %compression
+  "zlib@openssh.com,zlib")
+
+(define* (open-ssh-session host #:key user port
+                           (compression %compression))
+  "Open an SSH session for HOST and return it.  When USER and PORT are #f, use
+default values or whatever '~/.ssh/config' specifies; otherwise use them.
+Throw an error on failure."
+  (let ((session (make-session #:user user
+                               #:host host
+                               #:port port
+                               #:timeout 10       ;seconds
+                               ;; #:log-verbosity 'protocol
+
+                               ;; We need lightweight compression when
+                               ;; exchanging full archives.
+                               #:compression compression
+                               #:compression-level 3)))
+
+    ;; Honor ~/.ssh/config.
+    (session-parse-config! session)
+
+    (match (connect! session)
+      ('ok
+       ;; Use public key authentication, via the SSH agent if it's available.
+       (match (userauth-public-key/auto! session)
+         ('success
+          session)
+         (x
+          (disconnect! session)
+          (raise (condition
+                  (&message
+                   (message (format #f (_ "SSH authentication failed for '~a': ~a~%")
+                                    host (get-error session)))))))))
+      (x
+       ;; Connection failed or timeout expired.
+       (raise (condition
+               (&message
+                (message (format #f (_ "SSH connection to '~a' failed: ~a~%")
+                                 host (get-error session))))))))))
+
+(define* (remote-daemon-channel session
+                                #:optional
+                                (socket-name
+                                 "/var/guix/daemon-socket/socket"))
+  "Return an input/output port (an SSH channel) to the daemon at SESSION."
   (define redirect
     ;; Code run in SESSION to redirect the remote process' stdin/stdout to the
     ;; daemon's socket, à la socat.  The SSH protocol supports forwarding to
@@ -82,13 +128,20 @@ an SSH session.  Return a <nix-server> object."
              (_
               (primitive-exit 1)))))))
 
-  (let ((channel
-         (open-remote-pipe* session OPEN_BOTH
-                            ;; Sort-of shell-quote REDIRECT.
-                            "guile" "-c"
-                            (object->string
-                             (object->string redirect)))))
-    (open-connection #:port channel)))
+  (open-remote-pipe* session OPEN_BOTH
+                     ;; Sort-of shell-quote REDIRECT.
+                     "guile" "-c"
+                     (object->string
+                      (object->string redirect))))
+
+(define* (connect-to-remote-daemon session
+                                   #:optional
+                                   (socket-name
+                                    "/var/guix/daemon-socket/socket"))
+  "Connect to the remote build daemon listening on SOCKET-NAME over SESSION,
+an SSH session.  Return a <nix-server> object."
+  (open-connection #:port (remote-daemon-channel session)))
+
 
 (define (store-import-channel session)
   "Return an output port to which archives to be exported to SESSION's store
diff --git a/guix/store.scm b/guix/store.scm
index 2f05351767..683f071a83 100644
--- a/guix/store.scm
+++ b/guix/store.scm
@@ -39,7 +39,8 @@
   #:use-module (ice-9 regex)
   #:use-module (ice-9 vlist)
   #:use-module (ice-9 popen)
-  #:export (%daemon-socket-file
+  #:use-module (web uri)
+  #:export (%daemon-socket-uri
             %gc-roots-directory
             %default-substitute-urls
 
@@ -216,8 +217,8 @@
 (define %default-socket-path
   (string-append %state-directory "/daemon-socket/socket"))
 
-(define %daemon-socket-file
-  ;; File name of the socket the daemon listens too.
+(define %daemon-socket-uri
+  ;; URI or file name of the socket the daemon listens too.
   (make-parameter (or (getenv "GUIX_DAEMON_SOCKET")
                       %default-socket-path)))
 
@@ -350,6 +351,18 @@
   (message nix-protocol-error-message)
   (status  nix-protocol-error-status))
 
+(define-syntax-rule (system-error-to-connection-error file exp ...)
+  "Catch 'system-error' exceptions and translate them to
+'&nix-connection-error'."
+  (catch 'system-error
+    (lambda ()
+      exp ...)
+    (lambda args
+      (let ((errno (system-error-errno args)))
+        (raise (condition (&nix-connection-error
+                           (file file)
+                           (errno errno))))))))
+
 (define (open-unix-domain-socket file)
   "Connect to the Unix-domain socket at FILE and return it.  Raise a
 '&nix-connection-error' upon error."
@@ -358,21 +371,90 @@
              (socket PF_UNIX SOCK_STREAM 0)))
         (a (make-socket-address PF_UNIX file)))
 
-    (catch 'system-error
-      (lambda ()
-        (connect s a)
-        s)
-      (lambda args
-        ;; Translate the error to something user-friendly.
-        (let ((errno (system-error-errno args)))
-          (raise (condition (&nix-connection-error
-                             (file file)
-                             (errno errno)))))))))
+    (system-error-to-connection-error file
+      (connect s a)
+      s)))
 
-(define* (open-connection #:optional (file (%daemon-socket-file))
+(define (open-inet-socket host port)
+  "Connect to the Unix-domain socket at HOST:PORT and return it.  Raise a
+'&nix-connection-error' upon error."
+  (let ((sock (with-fluids ((%default-port-encoding #f))
+                ;; This trick allows use of the `scm_c_read' optimization.
+                (socket PF_UNIX SOCK_STREAM 0))))
+    (define addresses
+      (getaddrinfo host
+                   (if (number? port) (number->string port) port)
+                   (if (number? port)
+                       (logior AI_ADDRCONFIG AI_NUMERICSERV)
+                       AI_ADDRCONFIG)))
+
+    (let loop ((addresses addresses))
+      (match addresses
+        ((ai rest ...)
+         (let ((s (socket (addrinfo:fam ai)
+                          ;; TCP/IP only
+                          SOCK_STREAM IPPROTO_IP)))
+
+           (catch 'system-error
+             (lambda ()
+               (connect s (addrinfo:addr ai))
+               s)
+             (lambda args
+               ;; Connection failed, so try one of the other addresses.
+               (close s)
+               (if (null? rest)
+                   (raise (condition (&nix-connection-error
+                                      (file host)
+                                      (errno (system-error-errno args)))))
+                   (loop rest))))))))))
+
+(define (connect-to-daemon uri)
+  "Connect to the daemon at URI, a string that may be an actual URI or a file
+name."
+  (define (not-supported)
+    (raise (condition (&nix-connection-error
+                       (file uri)
+                       (errno ENOTSUP)))))
+
+  (define connect
+    (match (string->uri uri)
+      (#f                                         ;URI is a file name
+       open-unix-domain-socket)
+      ((? uri? uri)
+       (match (uri-scheme uri)
+         ((or #f 'file 'unix)
+          (lambda (_)
+            (open-unix-domain-socket (uri-path uri))))
+         ('guix
+          (lambda (_)
+            (unless (uri-port uri)
+              (raise (condition (&nix-connection-error
+                                 (file (uri->string uri))
+                                 (errno EBADR))))) ;bah!
+
+            (open-inet-socket (uri-host uri) (uri-port uri))))
+         ((? symbol? scheme)
+          ;; Try to dynamically load a module for SCHEME.
+          ;; XXX: Errors are swallowed.
+          (match (false-if-exception
+                  (resolve-interface `(guix store ,scheme)))
+            ((? module? module)
+             (match (false-if-exception
+                     (module-ref module 'connect-to-daemon))
+               ((? procedure? connect)
+                (lambda (_)
+                  (connect uri)))
+               (x (not-supported))))
+            (#f (not-supported))))
+         (x
+          (not-supported))))))
+
+  (connect uri))
+
+(define* (open-connection #:optional (uri (%daemon-socket-uri))
                           #:key port (reserve-space? #t) cpu-affinity)
-  "Connect to the daemon over the Unix-domain socket at FILE, or, if PORT is
-not #f, use it as the I/O port over which to communicate to a build daemon.
+  "Connect to the daemon at URI (a string), or, if PORT is not #f, use it as
+the I/O port over which to communicate to a build daemon.
 
 When RESERVE-SPACE? is true, instruct it to reserve a little bit of extra
 space on the file system so that the garbage collector can still operate,
@@ -383,10 +465,10 @@ for this connection will be pinned.  Return a server object."
              ;; One of the 'write-' or 'read-' calls below failed, but this is
              ;; really a connection error.
              (raise (condition
-                     (&nix-connection-error (file (or port file))
+                     (&nix-connection-error (file (or port uri))
                                             (errno EPROTO))
                      (&message (message "build daemon handshake failed"))))))
-    (let ((port (or port (open-unix-domain-socket file))))
+    (let ((port (or port (connect-to-daemon uri))))
       (write-int %worker-magic-1 port)
       (let ((r (read-int port)))
         (and (eqv? r %worker-magic-2)
@@ -1330,3 +1412,7 @@ must be an absolute store file name, or a derivation file name."
             ;; Return the first that works.
             (any (cut log-file store <>) derivers))
            (_ #f)))))
+
+;;; Local Variables:
+;;; eval: (put 'system-error-to-connection-error 'scheme-indent-function 1)
+;;; End:
diff --git a/guix/store/ssh.scm b/guix/store/ssh.scm
new file mode 100644
index 0000000000..09c0832505
--- /dev/null
+++ b/guix/store/ssh.scm
@@ -0,0 +1,39 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2017 Ludovic Courtès <ludo@gnu.org>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix store ssh)
+  #:use-module (guix ssh)
+  #:use-module (web uri)
+  #:export (connect-to-daemon))
+
+;;; Commentary:
+;;;
+;;; This modules provides the entry point for 'open-connection' in (guix
+;;; store).  Passing an 'ssh://' URI to 'open-connection' triggers the use of
+;;; the code in this module.
+;;;
+;;; End:
+
+(define (connect-to-daemon uri)
+  "Connect to the SSH daemon at URI, a URI object with the 'ssh' scheme."
+  (remote-daemon-channel
+   (open-ssh-session (uri-host uri)
+                     #:port (or (uri-port uri) 22)
+                     #:user (uri-userinfo uri))))
+
+;;; ssh.scm ends here
diff --git a/guix/tests.scm b/guix/tests.scm
index 5110075e7d..34e3e0fc2a 100644
--- a/guix/tests.scm
+++ b/guix/tests.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -56,13 +56,13 @@
    (or (and=> (getenv "GUIX_BINARY_SUBSTITUTE_URL") list)
        '())))
 
-(define* (open-connection-for-tests #:optional (file (%daemon-socket-file)))
+(define* (open-connection-for-tests #:optional (uri (%daemon-socket-uri)))
   "Open a connection to the build daemon for tests purposes and return it."
   (guard (c ((nix-error? c)
              (format (current-error-port)
                      "warning: build daemon error: ~s~%" c)
              #f))
-    (let ((store (open-connection file)))
+    (let ((store (open-connection uri)))
       ;; Make sure we build everything by ourselves.
       (set-build-options store
                          #:use-substitutes? #f
diff --git a/guix/workers.scm b/guix/workers.scm
new file mode 100644
index 0000000000..e3452d249a
--- /dev/null
+++ b/guix/workers.scm
@@ -0,0 +1,123 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2017 Ludovic Courtès <ludo@gnu.org>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix workers)
+  #:use-module (ice-9 threads)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 q)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-9)
+  #:use-module (srfi srfi-26)
+  #:export (pool?
+            make-pool
+            pool-enqueue!
+            pool-idle?
+            eventually))
+
+;;; Commentary:
+;;;
+;;; This module implements "worker pools".  Worker pools are the low-level
+;;; mechanism that's behind futures: there's a fixed set of threads
+;;; ("workers") that one can submit work to, and one of them will eventually
+;;; pick the submitted tasks.
+;;;
+;;; Unlike futures, these worker pools are meant to be used for tasks that
+;;; have a side-effect.  Thus, we never "touch" a task that was submitted like
+;;; we "touch" a future.  Instead, we simply assume that the task will
+;;; eventually complete.
+;;;
+;;; Code:
+
+(define-record-type <pool>
+  (%make-pool queue mutex condvar workers)
+  pool?
+  (queue    pool-queue)
+  (mutex    pool-mutex)
+  (condvar  pool-condition-variable)
+  (workers  pool-workers))
+
+(define-syntax-rule (without-mutex mutex exp ...)
+  (dynamic-wind
+    (lambda ()
+      (unlock-mutex mutex))
+    (lambda ()
+      exp ...)
+    (lambda ()
+      (lock-mutex mutex))))
+
+(define (worker-thunk mutex condvar pop-queue)
+  "Return the thunk executed by worker threads."
+  (define (loop)
+    (match (pop-queue)
+      (#f                                         ;empty queue
+       (wait-condition-variable condvar mutex))
+      ((? procedure? proc)
+       ;; Release MUTEX while executing PROC.
+       (without-mutex mutex
+         (catch #t proc
+           (lambda (key . args)
+             ;; XXX: In Guile 2.0 ports are not thread-safe, so this could
+             ;; crash (Guile 2.2 is fine).
+             (display-backtrace (make-stack #t) (current-error-port))
+             (print-exception (current-error-port)
+                              (stack-ref (make-stack #t) 0)
+                              key args))))))
+    (loop))
+
+  (lambda ()
+    (with-mutex mutex
+      (loop))))
+
+(define* (make-pool #:optional (count (current-processor-count)))
+  "Return a pool of COUNT workers."
+  (let* ((mutex   (make-mutex))
+         (condvar (make-condition-variable))
+         (queue   (make-q))
+         (procs   (unfold (cut >= <> count)
+                          (lambda (n)
+                            (worker-thunk mutex condvar
+                                          (lambda ()
+                                            (and (not (q-empty? queue))
+                                                 (q-pop! queue)))))
+                          1+
+                          0))
+         (threads (map (lambda (proc)
+                         (call-with-new-thread proc))
+                       procs)))
+    (%make-pool queue mutex condvar threads)))
+
+(define (pool-enqueue! pool thunk)
+  "Enqueue THUNK for future execution by POOL."
+  (with-mutex (pool-mutex pool)
+    (enq! (pool-queue pool) thunk)
+    (signal-condition-variable (pool-condition-variable pool))))
+
+(define (pool-idle? pool)
+  "Return true if POOL doesn't have any task in its queue."
+  (with-mutex (pool-mutex pool)
+    (q-empty? (pool-queue pool))))
+
+(define-syntax-rule (eventually pool exp ...)
+  "Run EXP eventually on one of the workers of POOL."
+  (pool-enqueue! pool (lambda () exp ...)))
+
+;;; Local Variables:
+;;; eval: (put 'without-mutex 'scheme-indent-function 1)
+;;; End:
+
+;;; workers.scm ends here
diff --git a/tests/cache.scm b/tests/cache.scm
new file mode 100644
index 0000000000..e46cdd816d
--- /dev/null
+++ b/tests/cache.scm
@@ -0,0 +1,88 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2017 Ludovic Courtès <ludo@gnu.org>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (test-cache)
+  #:use-module (guix cache)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-19)
+  #:use-module (srfi srfi-64)
+  #:use-module ((guix utils) #:select (call-with-temporary-directory))
+  #:use-module (ice-9 match))
+
+(cond-expand
+  (guile-2.2
+   ;; Guile 2.2.2 has a bug whereby 'time-monotonic' objects have seconds and
+   ;; nanoseconds swapped (fixed in Guile commit 886ac3e).  Work around it.
+   (define time-monotonic time-tai))
+  (else #t))
+
+(test-begin "cache")
+
+(test-equal "remove-expired-cache-entries"
+  '("o" "l" "d")
+  (let* ((removed '())
+         (now     (time-second (current-time time-monotonic)))
+         (ttl     100)
+         (stamp   (match-lambda
+                    ((or "n" "e" "w") (+ now 100))
+                    ((or "o" "l" "d") (- now 100))))
+         (delete  (lambda (entry)
+                    (set! removed (cons entry removed)))))
+    (remove-expired-cache-entries (reverse '("n" "e" "w"
+                                             "o" "l" "d"))
+                                  #:entry-expiration stamp
+                                  #:delete-entry delete)
+    removed))
+
+(define-syntax-rule (test-cache-cleanup cache exp ...)
+  (call-with-temporary-directory
+   (lambda (cache)
+     (let* ((deleted '())
+            (delete! (lambda (entry)
+                       (set! deleted (cons entry deleted)))))
+       exp ...
+       (maybe-remove-expired-cache-entries cache
+                                           (const '("a" "b" "c"))
+                                           #:entry-expiration (const 0)
+                                           #:delete-entry delete!)
+       (reverse deleted)))))
+
+(test-equal "maybe-remove-expired-cache-entries, first cleanup"
+  '("a" "b" "c")
+  (test-cache-cleanup cache))
+
+(test-equal "maybe-remove-expired-cache-entries, no cleanup needed"
+  '()
+  (test-cache-cleanup cache
+    (call-with-output-file (string-append cache "/last-expiry-cleanup")
+      (lambda (port)
+        (display (+ (time-second (current-time time-monotonic)) 100)
+                 port)))))
+
+(test-equal "maybe-remove-expired-cache-entries, cleanup needed"
+  '("a" "b" "c")
+  (test-cache-cleanup cache
+    (call-with-output-file (string-append cache "/last-expiry-cleanup")
+      (lambda (port)
+        (display 0 port)))))
+
+(test-end "cache")
+
+;;; Local Variables:
+;;; eval: (put 'test-cache-cleanup 'scheme-indent-function 1)
+;;; End:
diff --git a/tests/derivations.scm b/tests/derivations.scm
index 75c8d1dfb1..cabbf7b951 100644
--- a/tests/derivations.scm
+++ b/tests/derivations.scm
@@ -701,6 +701,20 @@
                                   #:modules '((guix module that
                                                     does not exist)))))
 
+(test-equal "build-expression->derivation and builder encoding"
+  '("UTF-8" #t)
+  (let* ((exp '(λ (α) (+ α 1)))
+         (drv (build-expression->derivation %store "foo" exp)))
+    (match (derivation-builder-arguments drv)
+      ((... builder)
+       (with-fluids ((%default-port-encoding "UTF-8"))
+         (call-with-input-file builder
+           (lambda (port)
+             (list (port-encoding port)
+                   (->bool
+                    (string-contains (get-string-all port)
+                                     "(λ (α) (+ α 1))"))))))))))
+
 (test-assert "build-expression->derivation and derivation-prerequisites"
   (let ((drv (build-expression->derivation %store "fail" #f)))
     (any (match-lambda
diff --git a/tests/gexp.scm b/tests/gexp.scm
index 41a53ae5a4..cf88a9db80 100644
--- a/tests/gexp.scm
+++ b/tests/gexp.scm
@@ -627,6 +627,10 @@
    #~(foo #$@(list (with-imported-modules '((foo)) #~+)
                    (with-imported-modules '((bar)) #~-)))))
 
+(test-equal "gexp-modules and literal Scheme object"
+  '()
+  (gexp-modules #t))
+
 (test-assertm "gexp->derivation #:modules"
   (mlet* %store-monad
       ((build ->  #~(begin
diff --git a/tests/guix-build.sh b/tests/guix-build.sh
index ab911b7210..9494e7371f 100644
--- a/tests/guix-build.sh
+++ b/tests/guix-build.sh
@@ -36,6 +36,14 @@ guix build -e '(@@ (gnu packages bootstrap) %bootstrap-guile)' |	\
 guix build hello -d |				\
     grep -e '-hello-[0-9\.]\+\.drv$'
 
+# Passing a URI.
+GUIX_DAEMON_SOCKET="file://$NIX_STATE_DIR/daemon-socket/socket"	\
+guix build -e '(@@ (gnu packages bootstrap) %bootstrap-guile)'
+
+( if GUIX_DAEMON_SOCKET="weird://uri"					\
+     guix build -e '(@@ (gnu packages bootstrap) %bootstrap-guile)';	\
+  then exit 1; fi )
+
 # Check --sources option with its arguments
 module_dir="t-guix-build-$$"
 mkdir "$module_dir"
diff --git a/tests/publish.scm b/tests/publish.scm
index ea0f4a3477..233b71ce93 100644
--- a/tests/publish.scm
+++ b/tests/publish.scm
@@ -314,4 +314,58 @@ References: ~%"
                               (call-with-input-string "" port-sha256))))))
     (response-code (http-get uri))))
 
+(unless (zlib-available?)
+  (test-skip 1))
+(test-equal "with cache"
+  (list #t
+        `(("StorePath" . ,%item)
+          ("URL" . ,(string-append "nar/gzip/" (basename %item)))
+          ("Compression" . "gzip"))
+        200                                       ;nar/gzip/…
+        #t                                        ;Content-Length
+        200)                                      ;nar/…
+  (call-with-temporary-directory
+   (lambda (cache)
+     (define (wait-for-file file)
+       (let loop ((i 20))
+         (or (file-exists? file)
+             (begin
+               (pk 'wait-for-file file)
+               (sleep 1)
+               (loop (- i 1))))))
+
+     (let ((thread (with-separate-output-ports
+                    (call-with-new-thread
+                     (lambda ()
+                       (guix-publish "--port=6797" "-C2"
+                                     (string-append "--cache=" cache)))))))
+       (wait-until-ready 6797)
+       (let* ((base     "http://localhost:6797/")
+              (part     (store-path-hash-part %item))
+              (url      (string-append base part ".narinfo"))
+              (nar-url  (string-append base "/nar/gzip/" (basename %item)))
+              (cached   (string-append cache "/gzip/" (basename %item)
+                                       ".narinfo"))
+              (nar      (string-append cache "/gzip/"
+                                       (basename %item) ".nar"))
+              (response (http-get url)))
+         (and (= 404 (response-code response))
+              (wait-for-file cached)
+              (let ((body         (http-get-port url))
+                    (compressed   (http-get nar-url))
+                    (uncompressed (http-get (string-append base "nar/"
+                                                           (basename %item)))))
+                (list (file-exists? nar)
+                      (filter (lambda (item)
+                                (match item
+                                  (("Compression" . _) #t)
+                                  (("StorePath" . _)  #t)
+                                  (("URL" . _) #t)
+                                  (_ #f)))
+                              (recutils->alist body))
+                      (response-code compressed)
+                      (= (response-content-length compressed)
+                         (stat:size (stat nar)))
+                      (response-code uncompressed)))))))))
+
 (test-end "publish")
diff --git a/tests/scripts-build.scm b/tests/scripts-build.scm
index a1f684c736..a408ea6f8d 100644
--- a/tests/scripts-build.scm
+++ b/tests/scripts-build.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2016, 2017 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -23,6 +23,7 @@
   #:use-module (guix scripts build)
   #:use-module (guix ui)
   #:use-module (guix utils)
+  #:use-module (gnu packages)
   #:use-module (gnu packages base)
   #:use-module (gnu packages busybox)
   #:use-module (ice-9 match)
@@ -97,8 +98,8 @@
 
 (test-assert "options->transformation, with-input"
   (let* ((p (dummy-package "guix.scm"
-              (inputs `(("foo" ,coreutils)
-                        ("bar" ,grep)
+              (inputs `(("foo" ,(specification->package "coreutils"))
+                        ("bar" ,(specification->package "grep"))
                         ("baz" ,(dummy-package "chbouib"
                                   (native-inputs `(("x" ,grep)))))))))
          (t (options->transformation '((with-input . "coreutils=busybox")
diff --git a/tests/store.scm b/tests/store.scm
index 45150d36ca..3eb8b7be5a 100644
--- a/tests/store.scm
+++ b/tests/store.scm
@@ -48,6 +48,14 @@
 
 (test-begin "store")
 
+(test-assert "open-connection with file:// URI"
+  (let ((store (open-connection (string-append "file://"
+                                               (%daemon-socket-uri)))))
+    (and (add-text-to-store store "foo" "bar")
+         (begin
+           (close-connection store)
+           #t))))
+
 (test-equal "connection handshake error"
   EPROTO
   (let ((port (%make-void-port "rw")))
diff --git a/tests/workers.scm b/tests/workers.scm
new file mode 100644
index 0000000000..44b882f691
--- /dev/null
+++ b/tests/workers.scm
@@ -0,0 +1,45 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2017 Ludovic Courtès <ludo@gnu.org>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (test-workers)
+  #:use-module (guix workers)
+  #:use-module (ice-9 threads)
+  #:use-module (srfi srfi-64))
+
+(test-begin "workers")
+
+(test-equal "enqueue"
+  4242
+  (let* ((pool   (make-pool))
+         (result 0)
+         (1+!    (let ((lock (make-mutex)))
+                   (lambda ()
+                     (with-mutex lock
+                       (set! result (+ result 1)))))))
+    (let loop ((i 4242))
+      (unless (zero? i)
+        (pool-enqueue! pool 1+!)
+        (loop (- i 1))))
+    (let poll ()
+      (unless (pool-idle? pool)
+        (pk 'busy result)
+        (sleep 1)
+        (poll)))
+    result))
+
+(test-end)