Subject: [PATCH] gnu: Add gnunet-scheme

From: Maxime Devos <[email-masked]>
Date: Fri, 04 Feb 2022 12:47:17 +0100

X-Debbugs-CC: pukkamustard <[email-masked]>, pukkamustard <[email-masked]>

[CC'ing pukkamustard and ludo for their interest in Guix+GNUnet]

Hi,

The first patch adds a module to guile-fibers required by gnunet-scheme.  It has been submitted upstream at <https://github.com/wingo/fibers/pull/50>, but there has not been any response so far.

The second commit adds 'gnunet-scheme', which is not the same as guile-gnunet:

"This package provides Guile modules for connecting to the NSE (network
size estimation) and DHT (distributed hash table) services of GNUnet.  It also
has infrastructure for writing new GNUnet services and connecting to them and
can be used from multi-threaded environments.  It is not to be confused with
@code{guile-gnunet} -- @code{guile-gnunet} supports a different set of services."

gnunet-scheme supports the DHT and NSE, while guile-gnunet doesn't.
Conversely, guile-gnunet supports FS while gnunet-scheme doesn't (yet).
Additionally, while it's not impossible per se, guile-gnunet is hard
to use from a multi-threaded context.

Next step: integrate it with guile-eris and the substituter patches based
on guile-eris (currently these only support IPFS as P2P backend)!

'guix lint gnunet-scheme guile-fibers' only have a single complaint:

gnu/packages/gnunet.scm:379:12: [email-masked]: URI https://git.gnunet.org/git/gnunet-scheme.git not reachable: 404 ("Not Found")

"guix build gnunet-scheme" could download the source code though,
so I don't understand.

It fails to cross-compile because guile-fibers fails to cross-compile:

> checking for guile-3.0... yes
> checking for guile-3.0... no
> checking for guile3.0... no
> checking for guile-3... no
> checking for guile3... no
> checking for guile... no
> configure: error: guile required but not found

That's unrelated to gnunet-scheme though.

Greetings,
Maxime
From 8272cceae8642ed89eb3ebc110821a395f3ae087 Mon Sep 17 00:00:00 2001
From: Maxime Devos <[email-masked]>
Date: Fri, 4 Feb 2022 11:16:46 +0000
Subject: [PATCH 1/2] gnu: guile-fibers: Add (fibers io-wakeup).

This patch is required by gnunet-scheme.  It has been submitted upstream at
<https://github.com/wingo/fibers/pull/50>, but there has not been any response
so far.

* gnu/packages/patches/guile-fibers-wait-for-io-readiness.patch: New file.
* gnu/packages/guile-xyz.scm (guile-fibers-1.1)[source]{patches}: Add it.
* gnu/local.mk (dist_patch_DATA): Add it.
---
 gnu/local.mk                                  |   1 +
 gnu/packages/guile-xyz.scm                    |  14 +-
 .../guile-fibers-wait-for-io-readiness.patch  | 346 ++++++++++++++++++
 3 files changed, 359 insertions(+), 2 deletions(-)
 create mode 100644 gnu/packages/patches/guile-fibers-wait-for-io-readiness.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index dddda78efa..18995fa5f8 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1231,6 +1231,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/guile-3.0-linux-syscalls.patch		\
   %D%/packages/patches/guile-3.0.7-psyntax-nil.patch		\
   %D%/packages/patches/guile-fibers-destroy-peer-schedulers.patch \
+  %D%/packages/patches/guile-fibers-wait-for-io-readiness.patch \
   %D%/packages/patches/guile-gdbm-ffi-support-gdbm-1.14.patch	\
   %D%/packages/patches/guile-git-adjust-for-libgit2-1.2.0.patch \
   %D%/packages/patches/guile-present-coding.patch		\
diff --git a/gnu/packages/guile-xyz.scm b/gnu/packages/guile-xyz.scm
index f35ba43057..31405de9eb 100644
--- a/gnu/packages/guile-xyz.scm
+++ b/gnu/packages/guile-xyz.scm
@@ -39,6 +39,7 @@
 ;;; Copyright © 2021 Zelphir Kaltstahl <[email-masked]>
 ;;; Copyright © 2021 Oleg Pykhalov <[email-masked]>
 ;;; Copyright © 2021, 2022 Artyom V. Poptsov <[email-masked]>
+;;; Copyright © 2022 Maxime Devos <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -612,10 +613,17 @@ Unix-style DSV format and RFC 4180 format.")
                     version "/fibers-" version ".tar.gz"))
               (sha256
                (base32
-                "1lqz39shlhif5fhpyv2wili0yzb0nhf5ciiv7mdqsq0vljirhrm0"))))
+                "1lqz39shlhif5fhpyv2wili0yzb0nhf5ciiv7mdqsq0vljirhrm0"))
+              (patches
+               (search-patches "guile-fibers-wait-for-io-readiness.patch"))))
     (build-system gnu-build-system)
     (arguments
      '(#:phases (modify-phases %standard-phases
+                  ;; This is required to make
+                  ;; "guile-fibers-wait-for-io-readiness.patch" work.
+                  (add-after 'unpack 'regenerate-autotools
+                    (lambda _
+                      (delete-file "configure")))
                   (add-after 'install 'mode-guile-objects
                     (lambda* (#:key outputs #:allow-other-keys)
                       ;; .go files are installed to "lib/guile/X.Y/cache".
@@ -629,7 +637,9 @@ Unix-style DSV format and RFC 4180 format.")
                         (rename-file old new)
                         #t))))))
     (native-inputs
-     (list texinfo pkg-config))
+     (list texinfo pkg-config autoconf automake libtool
+           ;; Gettext brings 'AC_LIB_LINKFLAGS_FROM_LIBS'
+           gettext-minimal))
     (inputs
      (list guile-3.0))
     (synopsis "Lightweight concurrency facility for Guile")
diff --git a/gnu/packages/patches/guile-fibers-wait-for-io-readiness.patch b/gnu/packages/patches/guile-fibers-wait-for-io-readiness.patch
new file mode 100644
index 0000000000..d5d5cf44e6
--- /dev/null
+++ b/gnu/packages/patches/guile-fibers-wait-for-io-readiness.patch
@@ -0,0 +1,346 @@
+Scheme-GNUnet requires the new operations 'wait-until-port-readable-operation'
+and 'wait-until-port-readable-operation' for communicating with services.
+This patch has been previously submitted at <https://github.com/wingo/fibers/pull/50>,
+on Sep 16, 2021.  As of Feb 3, 2022, upstream has not responded yet.
+
+diff --git a/Makefile.am b/Makefile.am
+index e2db57e..0134255 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -33,6 +33,7 @@ SOURCES = \
+ 	fibers/deque.scm \
+ 	fibers/epoll.scm \
+ 	fibers/interrupts.scm \
++	fibers/io-wakeup.scm \
+ 	fibers/nameset.scm \
+ 	fibers/operations.scm \
+ 	fibers/posix-clocks.scm \
+@@ -67,6 +68,7 @@ TESTS = \
+ 	tests/conditions.scm \
+ 	tests/channels.scm \
+ 	tests/foreign.scm \
++	tests/io-wakeup.scm \
+ 	tests/parameters.scm \
+ 	tests/preemption.scm \
+ 	tests/speedup.scm
+diff --git a/fibers.texi b/fibers.texi
+index 52f7177..0990c8f 100644
+--- a/fibers.texi
++++ b/fibers.texi
+@@ -12,6 +12,7 @@ This manual is for Fibers (version @value{VERSION}, updated
+ @value{UPDATED})
+ 
+ Copyright 2016-2022 Andy Wingo
++Copyright 2021 Maxime Devos
+ 
+ @quotation
+ @c For more information, see COPYING.docs in the fibers
+@@ -453,6 +454,7 @@ of operations for channels and timers, and an internals interface.
+ * Channels::             Share memory by communicating.
+ * Timers::               Operations on time.
+ * Conditions::           Waiting for simple state changes.
++* Port Readiness::       Waiting until a port is ready for I/O.
+ * REPL Commands::        Experimenting with Fibers at the console.
+ * Schedulers and Tasks:: Fibers are built from lower-level primitives.
+ @end menu
+@@ -722,6 +724,28 @@ signalled.  Equivalent to @code{(perform-operation (wait-operation
+ cvar))}.
+ @end defun
+ 
++@node Port Readiness
++@section Port Readiness
++
++These two operations can be used on file ports to wait until
++they are readable or writable.  Spurious wake-ups are possible.
++This is complementary to Guile's suspendable ports.
++
++@example
++(use-modules (fibers io-wakeup))
++@end example
++
++@defun wait-until-port-readable-operation port
++Make an operation that will succeed with no values when the input
++port @var{port} becomes readable.  For passive sockets, this operation
++succeeds when a connection becomes available.
++@end defun
++
++@defun wait-until-port-writable-operation
++Make an operation that will succeed with no values when the output
++port @var{port} becomes writable.
++@end defun
++
+ @node REPL Commands
+ @section REPL Commands
+ 
+diff --git a/fibers/io-wakeup.scm b/fibers/io-wakeup.scm
+new file mode 100644
+index 0000000..5df03f1
+--- /dev/null
++++ b/fibers/io-wakeup.scm
+@@ -0,0 +1,93 @@
++;; Fibers: cooperative, event-driven user-space threads.
++
++;;;; Copyright (C) 2016,2021 Free Software Foundation, Inc.
++;;;; Copyright (C) 2021 Maxime Devos
++;;;;
++;;;; This library is free software; you can redistribute it and/or
++;;;; modify it under the terms of the GNU Lesser General Public
++;;;; License as published by the Free Software Foundation; either
++;;;; version 3 of the License, or (at your option) any later version.
++;;;;
++;;;; This library 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
++;;;; Lesser General Public License for more details.
++;;;;
++;;;; You should have received a copy of the GNU Lesser General Public
++;;;; License along with this library; if not, write to the Free Software
++;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++;;;;
++
++(define-module (fibers io-wakeup)
++  #:use-module (fibers scheduler)
++  #:use-module (fibers operations)
++  #:use-module (ice-9 atomic)
++  #:use-module (ice-9 match)
++  #:use-module (ice-9 threads)
++  #:use-module (ice-9 ports internal)
++  #:export (wait-until-port-readable-operation
++	    wait-until-port-writable-operation))
++
++(define *poll-sched* (make-atomic-box #f))
++
++(define (poll-sched)
++  (or (atomic-box-ref *poll-sched*)
++      (let ((sched (make-scheduler)))
++        (cond
++         ((atomic-box-compare-and-swap! *poll-sched* #f sched))
++         (else
++          ;; FIXME: Would be nice to clean up this thread at some point.
++          (call-with-new-thread
++           (lambda ()
++             (define (finished?) #f)
++             (run-scheduler sched finished?)))
++          sched)))))
++
++;; These procedure are subject to spurious wakeups.
++
++(define (readable? port)
++  "Test if PORT is writable."
++  (match (select (vector port) #() #() 0)
++    ((#() #() #()) #f)
++    ((#(_) #() #()) #t)))
++
++(define (writable? port)
++  "Test if PORT is writable."
++  (match (select #() (vector port) #() 0)
++    ((#() #() #()) #f)
++    ((#() #(_) #()) #t)))
++
++(define (make-wait-operation ready? schedule-when-ready port port-ready-fd this-procedure)
++  (make-base-operation #f
++                       (lambda _
++                         (and (ready? port) values))
++                       (lambda (flag sched resume)
++                         (define (commit)
++                           (match (atomic-box-compare-and-swap! flag 'W 'S)
++                             ('W (resume values))
++                             ('C (commit))
++                             ('S #f)))
++                         (if sched
++                             (schedule-when-ready
++                              sched (port-ready-fd port) commit)
++                             (schedule-task
++                              (poll-sched)
++                              (lambda ()
++                                (perform-operation (this-procedure port))
++                                (commit)))))))
++
++(define (wait-until-port-readable-operation port)
++  "Make an operation that will succeed when PORT is readable."
++  (unless (input-port? port)
++    (error "refusing to wait forever for input on non-input port"))
++  (make-wait-operation readable? schedule-task-when-fd-readable port
++                       port-read-wait-fd
++                       wait-until-port-readable-operation))
++
++(define (wait-until-port-writable-operation port)
++  "Make an operation that will succeed when PORT is writable."
++  (unless (output-port? port)
++    (error "refusing to wait forever for output on non-output port"))
++  (make-wait-operation writable? schedule-task-when-fd-writable port
++                       port-write-wait-fd
++                       wait-until-port-writable-operation))
+diff --git a/tests/io-wakeup.scm b/tests/io-wakeup.scm
+new file mode 100644
+index 0000000..c14fa81
+--- /dev/null
++++ b/tests/io-wakeup.scm
+@@ -0,0 +1,167 @@
++;; Fibers: cooperative, event-driven user-space threads.
++
++;;;; Copyright (C) 2016 Free Software Foundation, Inc.
++;;;; Copyright (C) 2021 Maxime Devos
++;;;;
++;;;; This library is free software; you can redistribute it and/or
++;;;; modify it under the terms of the GNU Lesser General Public
++;;;; License as published by the Free Software Foundation; either
++;;;; version 3 of the License, or (at your option) any later version.
++;;;;
++;;;; This library 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
++;;;; Lesser General Public License for more details.
++;;;;
++;;;; You should have received a copy of the GNU Lesser General Public
++;;;; License along with this library; if not, write to the Free Software
++;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++;;;;
++
++(define-module (tests io-wakeup)
++  #:use-module (rnrs bytevectors)
++  #:use-module (ice-9 control)
++  #:use-module (ice-9 suspendable-ports)
++  #:use-module (ice-9 binary-ports)
++  #:use-module (fibers)
++  #:use-module (fibers io-wakeup)
++  #:use-module (fibers operations)
++  #:use-module (fibers timers))
++
++(define failed? #f)
++
++(define-syntax-rule (assert-equal expected actual)
++  (let ((x expected))
++    (format #t "assert ~s equal to ~s: " 'actual x)
++    (force-output)
++    (let ((y actual))
++      (cond
++       ((equal? x y) (format #t "ok\n"))
++       (else
++        (format #t "no (got ~s)\n" y)
++        (set! failed? #t))))))
++
++(define-syntax-rule (assert-run-fibers-terminates exp)
++  (begin
++    (format #t "assert run-fibers on ~s terminates: " 'exp)
++    (force-output)
++    (let ((start (get-internal-real-time)))
++      (call-with-values (lambda () (run-fibers (lambda () exp)))
++        (lambda vals
++          (format #t "ok (~a s)\n" (/ (- (get-internal-real-time) start)
++                                      1.0 internal-time-units-per-second))
++          (apply values vals))))))
++
++(define-syntax-rule (assert-run-fibers-returns (expected ...) exp)
++  (begin
++    (call-with-values (lambda () (assert-run-fibers-terminates exp))
++      (lambda run-fiber-return-vals
++        (assert-equal '(expected ...) run-fiber-return-vals)))))
++
++
++;; Note that theoretically, on very slow systems, SECONDS might need
++;; to be increased.  However, readable/timeout? and writable/timeout?
++;; call this 5 times in a loop anyways, so the effective timeout is
++;; a fourth of a second, which should be plenty in practice.
++(define* (with-timeout op #:key (seconds 0.05) (wrap values))
++  (choice-operation op
++                    (wrap-operation (sleep-operation seconds) wrap)))
++
++(define* (readable/timeout? port #:key (allowed-spurious 5))
++  "Does waiting for readability time-out?
++Allow @var{allowed-spurious} spurious wakeups."
++  (or (perform-operation
++	(with-timeout
++	 (wrap-operation (wait-until-port-readable-operation port)
++			 (lambda () #f))
++	 #:wrap (lambda () #t)))
++      (and (> allowed-spurious 0)
++	   (readable/timeout? port #:allowed-spurious
++			      (- allowed-spurious 1)))))
++
++(define* (writable/timeout? port #:key (allowed-spurious 5))
++  "Does waiting for writability time-out?
++Allow @var{allowed-spurious} spurious wakeups."
++  (or (perform-operation
++       (with-timeout
++	(wrap-operation (wait-until-port-writable-operation port)
++			(lambda () #f))
++	#:wrap (lambda () #t)))
++      (and (> allowed-spurious 0)
++	   (writable/timeout? port #:allowed-spurious
++			      (- allowed-spurious 1)))))
++
++;; Tests:
++;;  * wait-until-port-readable-operaton / wait-until-port-writable-operation
++;;    blocks if the port isn't ready for input / output.
++;;
++;;    This is tested with a pipe (read & write)
++;;    and a listening socket (read, or accept in this case).
++;;
++;;    Due to the possibility of spurious wakeups,
++;;    a limited few spurious wakeups are tolerated.
++;;
++;;  * these operations succeed if the port is ready for input / output.
++;;
++;;    These are again tested with a pipe and a listening socket
++;;
++;; Blocking is detected with a small time-out.
++
++(define (make-listening-socket)
++  (let ((server (socket PF_INET SOCK_DGRAM 0)))
++    (bind server AF_INET INADDR_LOOPBACK 0)
++    server))
++
++(let ((s (make-listening-socket)))
++  (assert-run-fibers-returns (#t)
++			     (readable/timeout? s))
++  (assert-equal #t (readable/timeout? s))
++  (close s))
++
++(define (set-nonblocking! sock)
++  (let ((flags (fcntl sock F_GETFL)))
++    (fcntl sock F_SETFL (logior O_NONBLOCK flags))))
++
++(define-syntax-rule (with-pipes (A B) exp exp* ...)
++  (let* ((pipes (pipe))
++	 (A (car pipes))
++	 (B (cdr pipes)))
++    exp exp* ...
++    (close A)
++    (close B)))
++
++(with-pipes (A B)
++  (setvbuf A 'none)
++  (setvbuf B 'none)
++  (assert-run-fibers-returns (#t)
++			     (readable/timeout? A))
++  (assert-equal #t (readable/timeout? A))
++
++  ;; The buffer is empty, so writability is expected.
++  (assert-run-fibers-returns (#f)
++			     (writable/timeout? B))
++  (assert-equal #f (writable/timeout? B))
++
++  ;; Fill the buffer
++  (set-nonblocking! B)
++  (let ((bv (make-bytevector 1024)))
++    (let/ec k
++      (parameterize ((current-write-waiter k))
++	(let loop ()
++	  (put-bytevector B bv)
++	  (loop)))))
++
++  ;; As the buffer is full, writable/timeout? should return
++  ;; #t.
++  (assert-run-fibers-returns (#t)
++			     (writable/timeout? B))
++  ;; There's plenty to read now, so readable/timeout? should
++  ;; return #f.
++  (assert-run-fibers-returns (#f)
++			     (readable/timeout? A)))
++
++(exit (if failed? 1 0))
++
++;; Local Variables:
++;; eval: (put 'with-pipes 'scheme-indent-function 1)
++;; End:

base-commit: 877da38bd3f279d5618d6c6517f48b50541a1e4c
-- 
2.30.2

From 5b57cdbb8f4d56c66885ea029cbe0a185d61a725 Mon Sep 17 00:00:00 2001
From: Maxime Devos <[email-masked]>
Date: Fri, 4 Feb 2022 11:23:36 +0000
Subject: [PATCH 2/2] gnu: Add gnunet-scheme.

This is not the same as guile-gnunet, see the description.

* gnu/packages/gnunet.scm (gnunet-scheme): New variable.
---
 gnu/packages/gnunet.scm | 58 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/gnu/packages/gnunet.scm b/gnu/packages/gnunet.scm
index 5c0dd348cc..1c09c9047b 100644
--- a/gnu/packages/gnunet.scm
+++ b/gnu/packages/gnunet.scm
@@ -11,6 +11,7 @@
 ;;; Copyright © 2019 Brett Gilio <[email-masked]>
 ;;; Copyright © 2020 Tanguy Le Carrour <[email-masked]>
 ;;; Copyright © 2020 Michael Rohleder <[email-masked]>
+;;; Copyright © 2022 Maxime Devos <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -42,6 +43,7 @@ (define-module (gnu packages gnunet)
   #:use-module (gnu packages groff)
   #:use-module (gnu packages gtk)
   #:use-module (gnu packages guile)
+  #:use-module (gnu packages guile-xyz)
   #:use-module (gnu packages gstreamer)
   #:use-module (gnu packages libidn)
   #:use-module (gnu packages linux)
@@ -58,10 +60,12 @@ (define-module (gnu packages gnunet)
   #:use-module (gnu packages pulseaudio)
   #:use-module (gnu packages python)
   #:use-module (gnu packages sqlite)
+  #:use-module (gnu packages text-editors)
   #:use-module (gnu packages tls)
   #:use-module (gnu packages upnp)
   #:use-module (gnu packages video)
   #:use-module (gnu packages vim)
+  #:use-module (gnu packages xorg)
   #:use-module (gnu packages web)
   #:use-module (gnu packages xiph)
   #:use-module (gnu packages backup)
@@ -368,6 +372,60 @@ (define-public guile-gnunet                       ;GSoC 2015!
       (home-page "https://gnu.org/software/guix")
       (license license:gpl3+))))
 
+(define-public gnunet-scheme
+  (package
+    (name "gnunet-scheme")
+    (version "0.2")
+    (source (origin
+              (method git-fetch)
+              (uri (git-reference
+                    (url "https://git.gnunet.org/git/gnunet-scheme.git")
+                    (commit (string-append "v" version))))
+              (file-name (git-file-name name version))
+              (sha256
+               (base32
+                "0a11n58m346vs2khns2hfnxv8lbscf8aaqzhmq0d7nwdpn808nrp"))
+              (modules '((guix build utils)))
+              ;; XXX: Work-around
+              ;; <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=49623>,
+              ;; this can be removed once Guile > 3.0.7 is released.
+              (snippet '(substitute* '("gnu/gnunet/config/parser.scm"
+                                       "tests/config-parser.scm")
+                          (("#\\{\\$\\{\\}\\}#") "#{${;};}#")
+                          (("#\\{\\$\\{:-\\}\\}#") "#{${;:-};}#")
+                          (("#\\{\\$\\{\\}\\}# #\\{\\$\\{:-\\}\\}#")
+                           "#{$\\x7b;\\x7d;}# #{$\\x7b;:-\\x7d;}#")
+                          (("'#\\{\\$\\{\\}\\}# '#\\{\\$\\{:-\\}\\}#")
+                           "'#{$\\x7b;\\x7d;}# '#{$\\x7b;:-\\x7d;}#")))))
+    (build-system gnu-build-system)
+    (inputs (list guile-3.0)) ;for pkg-config
+    (propagated-inputs (list guile-bytestructures guile-gcrypt guile-pfds
+                             guile-fibers-1.1))
+    (native-inputs (list guile-3.0 ;as a compiler
+                         ;; for cross-compilation, the guile inputs need to be
+                         ;; native-inputs as well.
+                         guile-bytestructures
+                         guile-gcrypt
+                         guile-pfds
+                         guile-fibers-1.1
+                         automake
+                         autoconf
+                         pkg-config
+                         texmacs
+                         xvfb-run ;for documentation
+                         guile-quickcheck)) ;for tests
+    (synopsis "Guile implementation of GNUnet client libraries")
+    (description
+     "This package provides Guile modules for connecting to the NSE (network
+size estimation) and DHT (distributed hash table) services of GNUnet.  It also
+has infrastructure for writing new GNUnet services and connecting to them and
+can be used from multi-threaded environments.  It is not to be confused with
+@code{guile-gnunet} -- @code{guile-gnunet} supports a different set of services.")
+    ;; Most code is licensed as AGPL and a few modules are licensed as LGPL
+    ;; or GPL.  Documentation is licensed as GFDL.
+    (license (list license:agpl3+ license:gpl3+ license:fdl1.3+ license:lgpl3+))
+    (home-page "https://git.gnunet.org/gnunet-scheme.git")))
+
 ;; FIXME: "gnunet-setup" segfaults under certain conditions and "gnunet-gtk"
 ;; does not seem to be fully functional.  This has been reported upstream:
 ;; http://lists.gnu.org/archive/html/gnunet-developers/2016-02/msg00004.html
-- 
2.34.0