Subject: [PATCH v2 1/2] gnu: knot-resolver: Update to 5.2.0.

From: Simon South <[email-masked]>
Date: Tue, 1 Dec 2020 09:45:19 -0500

* gnu/packages/dns.scm (knot-resolver): Update to 5.2.0.
[source]: Add patch from upstream commit to fix the internal map() function on
32-bit platforms.
[native-inputs]: Add texinfo to enable generating the manual in Info format.
[inputs]: Add nghttp2:lib to enable the new DNS-over-HTTPS implementation.
* gnu/packages/patches/knot-resolver-fix-map-command-on-32-bit.patch: New
file.
* gnu/local.mk (dist_patch_DATA): Add it.
---
 gnu/local.mk                                  |   1 +
 gnu/packages/dns.scm                          |  12 +-
 ...t-resolver-fix-map-command-on-32-bit.patch | 146 ++++++++++++++++++
 3 files changed, 155 insertions(+), 4 deletions(-)
 create mode 100644 gnu/packages/patches/knot-resolver-fix-map-command-on-32-bit.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 80f87691fe..e8d63c38df 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1221,6 +1221,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/kmail-Fix-missing-link-libraries.patch \
   %D%/packages/patches/kmod-module-directory.patch		\
   %D%/packages/patches/kmscon-runtime-keymap-switch.patch	\
+  %D%/packages/patches/knot-resolver-fix-map-command-on-32-bit.patch	\
   %D%/packages/patches/kpackage-allow-external-paths.patch	\
   %D%/packages/patches/kpackage-fix-KF5PackageMacros.cmake.patch \
   %D%/packages/patches/kmplayer-aarch64.patch			\
diff --git a/gnu/packages/dns.scm b/gnu/packages/dns.scm
index 3aa3cf3e8d..f0c3d6a602 100644
--- a/gnu/packages/dns.scm
+++ b/gnu/packages/dns.scm
@@ -937,14 +937,16 @@ synthesis, and on-the-fly re-configuration.")
 (define-public knot-resolver
   (package
     (name "knot-resolver")
-    (version "5.1.3")
+    (version "5.2.0")
     (source (origin
               (method url-fetch)
               (uri (string-append "https://secure.nic.cz/files/knot-resolver/"
                                   "knot-resolver-" version ".tar.xz"))
               (sha256
                (base32
-                "12s5070nqqf599s1mb6rjas2as481rjf751qk5yrz6p34y885k90"))))
+                "0cwlipib3x88dr6cijqv2aps13b4ijv524wc85ns07rkldy2c948"))
+               (patches
+                (search-patches "knot-resolver-fix-map-command-on-32-bit.patch"))))
     (build-system meson-build-system)
     (arguments
      '(#:configure-flags '("-Ddoc=enabled")
@@ -982,7 +984,8 @@ synthesis, and on-the-fly re-configuration.")
        ("pkg-config" ,pkg-config)
        ("python-breathe" ,python-breathe)
        ("python-sphinx" ,python-sphinx)
-       ("python-sphinx-rtd-theme" ,python-sphinx-rtd-theme)))
+       ("python-sphinx-rtd-theme" ,python-sphinx-rtd-theme)
+       ("texinfo" ,texinfo)))
     (inputs
      `(("fstrm" ,fstrm)
        ("gnutls" ,gnutls)
@@ -991,7 +994,8 @@ synthesis, and on-the-fly re-configuration.")
        ("lmdb" ,lmdb)
        ("luajit" ,luajit)
        ;; TODO: Add optional lua modules: basexx and psl.
-       ("lua-bitop" ,lua5.1-bitop)))
+       ("lua-bitop" ,lua5.1-bitop)
+       ("nghttp2" ,nghttp2 "lib")))
     (home-page "https://www.knot-resolver.cz/")
     (synopsis "Caching validating DNS resolver")
     (description
diff --git a/gnu/packages/patches/knot-resolver-fix-map-command-on-32-bit.patch b/gnu/packages/patches/knot-resolver-fix-map-command-on-32-bit.patch
new file mode 100644
index 0000000000..02c0fbcb70
--- /dev/null
+++ b/gnu/packages/patches/knot-resolver-fix-map-command-on-32-bit.patch
@@ -0,0 +1,146 @@
+commit e01979620025666633250b3e2d545fe59c629f73
+Author: Vladimír Čunát <[email-masked]>
+Date:   Fri Nov 13 14:16:32 2020 +0100
+
+    fix map() command on 32-bit platforms; regressed in 5.2.0
+    
+    LuaJIT FFI was using opendir() (etc.) variants with 32-bit inodes
+    but the C parts was using them as 64-bit inode variants.
+    Consequently the `struct dirent` layout didn't match and we were getting
+    filenames shifted by eight bytes.
+    
+    Now the whole dir-listing lua function is written in C.
+
+diff --git a/.luacheckrc b/.luacheckrc
+index 0cf0b884..67bc18f6 100644
+--- a/.luacheckrc
++++ b/.luacheckrc
+@@ -20,6 +20,7 @@ new_read_globals = {
+ 	'user',
+ 	'verbose',
+ 	'worker',
++	'kluautil_list_dir',
+ 	-- Sandbox declarations
+ 	'kB',
+ 	'MB',
+diff --git a/NEWS b/NEWS
+index 2eae3082..9d8cde99 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,10 @@
+ Knot Resolver X.Y.X (yyyy-mm-dd)
+ ================================
+ 
++Bugfixes
++--------
++- fix map() command on 32-bit platforms; regressed in 5.2.0 (!1093)
++
+ 
+ Knot Resolver 5.2.0 (2020-11-11)
+ ================================
+diff --git a/daemon/bindings/impl.c b/daemon/bindings/impl.c
+index d10f4525..d9ad0774 100644
+--- a/daemon/bindings/impl.c
++++ b/daemon/bindings/impl.c
+@@ -2,6 +2,7 @@
+  *  SPDX-License-Identifier: GPL-3.0-or-later
+  */
+ 
++#include <dirent.h>
+ #include <lua.h>
+ #include <lauxlib.h>
+ #include <string.h>
+@@ -29,6 +30,29 @@ const char * lua_table_checkindices(lua_State *L, const char *keys[])
+ 	return NULL;
+ }
+ 
++/** Return table listing filenames in a given directory (ls -A). */
++static int kluautil_list_dir(lua_State *L)
++{
++	lua_newtable(L); // empty table even on errors
++
++	const char *path = lua_tolstring(L, 1, NULL);
++	if (!path) return 1;
++	DIR *dir = opendir(path);
++	if (!dir) return 1;
++
++	struct dirent *entry;
++	int lua_i = 1;
++	while ((entry = readdir(dir)) != NULL) {
++		if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) {
++			lua_pushstring(L, entry->d_name);
++			lua_rawseti(L, -2, lua_i++);
++		}
++	}
++
++	closedir(dir);
++	return 1;
++}
++
+ 
+ /* Each of these just creates the correspondingly named lua table of functions. */
+ int kr_bindings_cache   (lua_State *L); /* ./cache.c   */
+@@ -44,6 +68,9 @@ void kr_bindings_register(lua_State *L)
+ 	kr_bindings_modules(L);
+ 	kr_bindings_net(L);
+ 	kr_bindings_worker(L);
++
++	/* Finally some lua utils *written in C*, not really a binding. */
++	lua_register(L, "kluautil_list_dir", kluautil_list_dir);
+ }
+ 
+ void lua_error_p(lua_State *L, const char *fmt, ...)
+diff --git a/daemon/lua/kluautil.lua b/daemon/lua/kluautil.lua
+index 57912e7b..e73e952c 100644
+--- a/daemon/lua/kluautil.lua
++++ b/daemon/lua/kluautil.lua
+@@ -1,6 +1,5 @@
+ -- SPDX-License-Identifier: GPL-3.0-or-later
+ 
+-local ffi = require('ffi')
+ local kluautil = {}
+ 
+ -- Get length of table
+@@ -28,14 +27,6 @@ function kluautil.kr_table_unpack(tab)
+ 	return unpack(tab, 1, tab.n)
+ end
+ 
+-ffi.cdef([[
+-	typedef struct __dirstream DIR;
+-	DIR *opendir(const char *name);
+-	struct dirent *readdir(DIR *dirp);
+-	int closedir(DIR *dirp);
+-	char *strerror(int errnum);
+-]])
+-
+ -- Fetch over HTTPS
+ function kluautil.kr_https_fetch(url, out_file, ca_file)
+ 	local http_ok, http_request = pcall(require, 'http.request')
+@@ -88,26 +79,6 @@ function kluautil.kr_https_fetch(url, out_file, ca_file)
+ 	return true
+ end
+ 
+--- List directory
+-function kluautil.list_dir (path)
+-	local results = {}
+-	local dir = ffi.C.opendir(path)
+-	if dir == nil then
+-		return results
+-	end
+-
+-	local entry = ffi.C.readdir(dir)
+-	while entry ~= nil do
+-		local entry_name = ffi.string(ffi.C.kr_dirent_name(entry))
+-		if entry_name ~= '.' and entry_name ~= '..' then
+-			table.insert(results, entry_name)
+-		end
+-		entry = ffi.C.readdir(dir)
+-	end
+-
+-	ffi.C.closedir(dir)
+-
+-	return results
+-end
++kluautil.list_dir = kluautil_list_dir
+ 
+ return kluautil
-- 
2.29.2