From: Ricardo Wurmus <rekado@elephly.net>
To: 26561@debbugs.gnu.org
Cc: Ricardo Wurmus <rekado@elephly.net>
Subject: bug#26561: [PATCH 9/9] gnu: Add policycoreutils.
Date: Wed, 19 Apr 2017 16:29:17 +0200 [thread overview]
Message-ID: <20170419142918.11688-9-rekado@elephly.net> (raw)
In-Reply-To: <20170419142918.11688-1-rekado@elephly.net>
* gnu/packages/selinux.scm (policycoreutils): New variable.
---
gnu/local.mk | 1 +
...policycoreutils-make-sepolicy-use-python3.patch | 335 +++++++++++++++++++++
gnu/packages/selinux.scm | 135 +++++++++
3 files changed, 471 insertions(+)
create mode 100644 gnu/packages/patches/policycoreutils-make-sepolicy-use-python3.patch
diff --git a/gnu/local.mk b/gnu/local.mk
index 77302573a..79ffbe2fe 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -856,6 +856,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 \
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 000000000..befe9fbb2
--- /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/selinux.scm b/gnu/packages/selinux.scm
index 05197b85c..7acda89a6 100644
--- a/gnu/packages/selinux.scm
+++ b/gnu/packages/selinux.scm
@@ -28,6 +28,10 @@
#: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)
@@ -338,3 +342,134 @@ 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/python3.5/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+)))
--
2.12.2
next prev parent reply other threads:[~2017-04-19 14:30 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-04-19 12:56 bug#26561: [PATCH 0/9] SELinux Ricardo Wurmus
2017-04-19 14:29 ` bug#26561: [PATCH 1/9] gnu: Add libsepol Ricardo Wurmus
2017-04-19 14:29 ` bug#26561: [PATCH 2/9] gnu: Add checkpolicy Ricardo Wurmus
2017-04-19 14:29 ` bug#26561: [PATCH 3/9] gnu: Add libselinux Ricardo Wurmus
2017-04-19 14:29 ` bug#26561: [PATCH 4/9] gnu: Add libsemanage Ricardo Wurmus
2017-04-19 14:29 ` bug#26561: [PATCH 5/9] gnu: Add secilc Ricardo Wurmus
2017-04-19 14:29 ` bug#26561: [PATCH 6/9] gnu: Add python-sepolgen Ricardo Wurmus
2017-04-19 14:29 ` bug#26561: [PATCH 7/9] gnu: Add python-ipy Ricardo Wurmus
2017-04-19 14:29 ` bug#26561: [PATCH 8/9] gnu: Add python-setools Ricardo Wurmus
2017-04-19 14:29 ` Ricardo Wurmus [this message]
2017-04-19 19:59 ` bug#26561: [PATCH 9/9] gnu: Add policycoreutils Marius Bakke
2017-04-19 19:57 ` bug#26561: [PATCH 1/9] gnu: Add libsepol Marius Bakke
2017-04-21 22:21 ` Ricardo Wurmus
2017-04-19 20:01 ` bug#26561: [PATCH 0/9] SELinux Marius Bakke
2017-04-20 8:30 ` julien lepiller
2017-04-21 22:40 ` Ricardo Wurmus
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170419142918.11688-9-rekado@elephly.net \
--to=rekado@elephly.net \
--cc=26561@debbugs.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/guix.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.