Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package util-linux for openSUSE:Factory 
checked in at 2025-10-18 14:35:53
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/util-linux (Old)
 and      /work/SRC/openSUSE:Factory/.util-linux.new.18484 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "util-linux"

Sat Oct 18 14:35:53 2025 rev:302 rq:1311767 version:2.41.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/util-linux/util-linux.changes    2025-09-10 
17:30:15.049556148 +0200
+++ /work/SRC/openSUSE:Factory/.util-linux.new.18484/util-linux.changes 
2025-10-18 14:36:46.991829706 +0200
@@ -1,0 +2,109 @@
+Thu Oct 16 01:24:14 UTC 2025 - Stanislav Brabec <[email protected]>
+
+- Include agetty netlink fixes from the final upstream commits
+  (jsc#PED-8734, util-linux-lib-netlink.patch and
+  util-linux-agetty-netlink.patch) and upstream fixes
+  (util-linux-lib-netlink-fix1.patch,
+  util-linux-lib-netlink-fix2.patch,
+  util-linux-lib-netlink-fix3.patch and
+  util-linux-agetty-netlink-fix4.patch).
+- Fix configs library use in agetty (replace
+  util-linux-issuedir-usr-lib.patch by upstream
+  util-linux-lib-configs-fix1.patch,
+  add util-linux-lib-configs-fix2.patch,
+  util-linux-lib-configs-fix3.patch,
+  util-linux-lib-configs-fix4.patch,
+  util-linux-lib-configs-fix5.patch and
+  util-linux-lib-configs-fix6.patch).
+- Fix agetty erase of escape characters (relevant to bsc#1194818,
+  util-linux-agetty-escape-erase.patch).
+- Own /usr/lib/issue.d directory.
+- Perform migration from issue-generator (jsc#PED-8734, fixes
+  boo#1244446).
+- Drop util-linux-agetty-ssh-host-keys.patch. This feature is not
+  used in MicroOS any more.
+- Remove Provides/Obsoletes for s390-32, upgrade from SLE11 SP1 is
+  no more supported.
+
+-------------------------------------------------------------------
+Tue Sep 30 18:35:50 UTC 2025 - Stanislav Brabec <[email protected]>
+
+- agetty: use /usr/lib/issue.d for backward compatibility
+  (util-linux-issuedir-usr-lib.patch).
+
+-------------------------------------------------------------------
+Sun Sep 28 07:15:32 UTC 2025 - Stanislav Brabec <[email protected]>
+
+- Fix address matching in agetty (boo#1247371,
+  util-linux-lib-netlink.patch).
+- Update generated man pages (util-linux-man-generated.patch).
+
+-------------------------------------------------------------------
+Fri Sep 26 02:28:52 UTC 2025 - Stanislav Brabec <[email protected]>
+
+- Add configs library and use it in agetty
+  (gh#util-linux/util-linux#3752,
+  util-linux-lib-configs.patch, util-linux-agetty-configs.patch).
+
+-------------------------------------------------------------------
+Wed Sep 24 22:48:35 UTC 2025 - Stanislav Brabec <[email protected]>
+
+- Update to version 2.41.2:
+  * bash-completion:
+    * fix function name of enosys completion
+    * add choom and coresched
+  * blkid: correct an erroneous error message
+  * findmnt:
+    * (usage) add a needed equals sign before an optional argument
+    * add missing newline in --raw, --pair and --list output
+      formats
+  * fsck.cramfs: check buffer size for memcpy()
+  * getopt: document special symbols that should not be used as
+    option characters
+  * hardlink (man): add note note about ULFILEEQ_DEBUG=
+  * libblkid:
+    * Fix probe_ioctl_tp assigning BLKGETDISKSEQ as physical sector
+      size
+    * (ext) reduce false positive
+    * improve UUID_SUB= description
+  * lib/color-names:
+    * fix stupid bugs
+    * Fix color name canonicalization
+  * libfdisk:
+    * (script) improve separator usage in named-fields dump
+    * (script) fix device name separator parsing
+  * liblastlog2: markup fixes for man pages
+  * libmount: don't report fsconfig errors with "nofail"
+  * lib/path: avoid double free() for cpusets
+  * lib (treewide): add ul_ prefix to functions with generic names
+  * logger:
+    * fix buffer overflow when read stdin
+    * fix incorrect warning message when both --file and a message
+      are specified
+  * lsblk:
+    * fix possible use-after-free
+    * fix memory leak [coverity scan]
+    * use md as fallback TYPE when md/level empty
+  * lscpu:
+    * New Arm C1 parts
+    * Add NVIDIA Olympus arm64 core (jsc#PED-13683)
+  * man:
+    * Fixed incorrect ipcrm options
+    * Replace RETURN VALUE with EXIT STATUS in section 1
+  * mkfs.cramfs: avoid uninitialized value [coverity scan]
+  * more: temporarily ignore stdin when waiting for stderr
+  * rev: add --zero option to --help output
+  * setpriv: Improve getgroups() Portability
+  * sfdisk: reject spurious arguments for
+    --reorder/--backup-pt-sectors
+  * zramctl:
+    * ignore ENOENT when setting max_comp_streams
+    * fix MEM-USED column description
+  * Misc: Add missing ;; to -m case (#1)
+  * tests fixes
+  * translation updates
+- Remove bash 5.3 hack for kill/decode. It is now fixed.
+- Mark test script/options as failing. It randomly fails on
+  aarch64, arm7l and s390x inside OBS (needs research).
+
+-------------------------------------------------------------------
@@ -5 +114 @@
-  issue file (util-linux-agetty-ssh-host-keys.patch.
+  issue file (util-linux-agetty-ssh-host-keys.patch).

Old:
----
  util-linux-2.41.1.tar.sign
  util-linux-2.41.1.tar.xz
  util-linux-agetty-ssh-host-keys.patch

New:
----
  util-linux-2.41.2.tar.sign
  util-linux-2.41.2.tar.xz
  util-linux-agetty-configs.patch
  util-linux-agetty-escape-erase.patch
  util-linux-agetty-netlink-fix4.patch
  util-linux-lib-configs-fix1.patch
  util-linux-lib-configs-fix2.patch
  util-linux-lib-configs-fix3.patch
  util-linux-lib-configs-fix4.patch
  util-linux-lib-configs-fix5.patch
  util-linux-lib-configs-fix6.patch
  util-linux-lib-configs.patch
  util-linux-lib-netlink-fix1.patch
  util-linux-lib-netlink-fix2.patch
  util-linux-lib-netlink-fix3.patch
  util-linux-man-generated.patch

----------(Old B)----------
  Old:  boo#1244446).
- Drop util-linux-agetty-ssh-host-keys.patch. This feature is not
  used in MicroOS any more.
----------(Old E)----------

----------(New B)----------
  New:  (gh#util-linux/util-linux#3752,
  util-linux-lib-configs.patch, util-linux-agetty-configs.patch).
  New:- Fix agetty erase of escape characters (relevant to bsc#1194818,
  util-linux-agetty-escape-erase.patch).
- Own /usr/lib/issue.d directory.
  New:  util-linux-lib-netlink-fix3.patch and
  util-linux-agetty-netlink-fix4.patch).
- Fix configs library use in agetty (replace
  New:  util-linux-issuedir-usr-lib.patch by upstream
  util-linux-lib-configs-fix1.patch,
  add util-linux-lib-configs-fix2.patch,
  New:  util-linux-lib-configs-fix1.patch,
  add util-linux-lib-configs-fix2.patch,
  util-linux-lib-configs-fix3.patch,
  New:  add util-linux-lib-configs-fix2.patch,
  util-linux-lib-configs-fix3.patch,
  util-linux-lib-configs-fix4.patch,
  New:  util-linux-lib-configs-fix3.patch,
  util-linux-lib-configs-fix4.patch,
  util-linux-lib-configs-fix5.patch and
  New:  util-linux-lib-configs-fix4.patch,
  util-linux-lib-configs-fix5.patch and
  util-linux-lib-configs-fix6.patch).
  New:  util-linux-lib-configs-fix5.patch and
  util-linux-lib-configs-fix6.patch).
- Fix agetty erase of escape characters (relevant to bsc#1194818,
  New:  (gh#util-linux/util-linux#3752,
  util-linux-lib-configs.patch, util-linux-agetty-configs.patch).
  New:  util-linux-agetty-netlink.patch) and upstream fixes
  (util-linux-lib-netlink-fix1.patch,
  util-linux-lib-netlink-fix2.patch,
  New:  (util-linux-lib-netlink-fix1.patch,
  util-linux-lib-netlink-fix2.patch,
  util-linux-lib-netlink-fix3.patch and
  New:  util-linux-lib-netlink-fix2.patch,
  util-linux-lib-netlink-fix3.patch and
  util-linux-agetty-netlink-fix4.patch).
  New:  util-linux-lib-netlink.patch).
- Update generated man pages (util-linux-man-generated.patch).
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ util-linux.spec ++++++
--- /var/tmp/diff_new_pack.slZcAX/_old  2025-10-18 14:36:47.951869868 +0200
+++ /var/tmp/diff_new_pack.slZcAX/_new  2025-10-18 14:36:47.951869868 +0200
@@ -85,7 +85,7 @@
 %endif
 # ulbuild == python
 
-Version:        2.41.1
+Version:        2.41.2
 Release:        0
 License:        GPL-2.0-or-later
 URL:            https://www.kernel.org/pub/linux/utils/util-linux/
@@ -114,8 +114,34 @@
 Patch6:         util-linux-lib-netlink.patch
 # PATCH-FEATURE-UPSTREAM util-linux-agetty-netlink.patch boo1139983 
jsc#PED-8734 [email protected] -- Implement netlink based IP address detection 
and issue reload.
 Patch7:         util-linux-agetty-netlink.patch
-# PATCH-FEATURE-OPENSUSE util-linux-agetty-ssh-host-keys.patch 
[email protected] -- Implement escape code for printing of ssh host keys in 
agetty issue file.
-Patch8:         util-linux-agetty-ssh-host-keys.patch
+# PATCH-FIX-UPSTREAM util-linux-lib-netlink-fix1.patch jsc#PED-8734 
[email protected] -- Implement netlink based IP address detection and issue 
reload.
+Patch8:         util-linux-lib-netlink-fix1.patch
+# PATCH-FIX-UPSTREAM util-linux-lib-netlink-fix2.patch jsc#PED-8734 
[email protected] -- Implement netlink based IP address detection and issue 
reload.
+Patch9:         util-linux-lib-netlink-fix2.patch
+# PATCH-FIX-UPSTREAM util-linux-lib-netlink-fix3.patch jsc#PED-8734 
[email protected] -- Implement netlink based IP address detection and issue 
reload.
+Patch10:        util-linux-lib-netlink-fix3.patch
+# PATCH-FIX-UPSTREAM util-linux-agetty-netlink-fix4.patch jsc#PED-8734 
[email protected] -- Implement netlink based IP address detection and issue 
reload.
+Patch11:        util-linux-agetty-netlink-fix4.patch
+# PATCH-FEATURE-UPSTREAM util-linux-lib-configs.patch 
gh#util-linux/util-linux#3752 [email protected] -- Added lib "configs" for 
parsing configuration.
+Patch12:        util-linux-lib-configs.patch
+# PATCH-FEATURE-UPSTREAM util-linux-agetty-configs.patch 
gh#util-linux/util-linux#3752 [email protected] -- agetty: using configs lib for 
parsing issue files.
+Patch13:        util-linux-agetty-configs.patch
+# PATCH-FIX-UPSTREAM util-linux-lib-configs-fix1.patch [email protected] -- Fix 
agetty: using configs lib.
+Patch14:        util-linux-lib-configs-fix1.patch
+# PATCH-FIX-UPSTREAM util-linux-lib-configs-fix2.patch [email protected] -- Fix 
agetty: using configs lib.
+Patch15:        util-linux-lib-configs-fix2.patch
+# PATCH-FIX-UPSTREAM util-linux-lib-configs-fix3.patch [email protected] -- Fix 
agetty: using configs lib.
+Patch16:        util-linux-lib-configs-fix3.patch
+# PATCH-FIX-UPSTREAM util-linux-lib-configs-fix4.patch [email protected] -- Fix 
agetty: using configs lib.
+Patch17:        util-linux-lib-configs-fix4.patch
+# PATCH-FIX-UPSTREAM util-linux-lib-configs-fix5.patch [email protected] -- Fix 
agetty: using configs lib.
+Patch18:        util-linux-lib-configs-fix5.patch
+# PATCH-FIX-UPSTREAM util-linux-lib-configs-fix6.patch [email protected] -- Fix 
agetty: using configs lib.
+Patch19:        util-linux-lib-configs-fix6.patch
+# PATCH-FIX-UPSTREAM util-linux-agetty-escape-erase.patch bsc#1194818 
[email protected] -- Fix agetty erase of escape characters.
+Patch20:        util-linux-agetty-escape-erase.patch
+# PATCH-FIX-BUILD util-linux-man-generated.patch [email protected] -- Update 
generated man pages modified by patches.
+Patch21:        util-linux-man-generated.patch
 BuildRequires:  audit-devel
 BuildRequires:  bc
 BuildRequires:  binutils-devel
@@ -179,20 +205,16 @@
 # The last version was 1.0+git.e66999f.
 Provides:       hardlink = 1.1
 Obsoletes:      hardlink < 1.1
-# bnc#805684:
-
-%ifarch s390x
-Obsoletes:      s390-32
-Provides:       s390-32
-%endif
-# arch s390x
-
+# New agetty fetures obsoleted issue-generator (up to SLE16 GA).
+Provides:       issue-generator = 1.13
+Obsoletes:      issue-generator <= 1.13
 Supplements:    filesystem(minix)
 # All login.defs variables require support from shadow side.
 # Upgrade this symbol version only if new variables appear!
 # Verify by shadow-login_defs-check.sh from shadow source package.
 # Use downstream version. Upstream may accept the patch later.
 Recommends:     login_defs-support-for-util-linux >= 4.17.4
+Requires(post): coreutils
 %endif
 # ulsubset == core
 
@@ -480,15 +502,6 @@
 %autopatch -p1
 # This test randomly fails or keeps hanging task inside build chroot (tested 
on 2.38).
 rm tests/ts/lsns/ioctl_ns
-# The bash-5.3 and up ignores SIGINT as well for async (co)processes,
-# rational https://lists.gnu.org/archive/html/bug-bash/2023-01/msg00050.html
-if test -n "$BASH_VERSION"
-then
-    if test ${BASH_VERSINFO[0]} -gt 5 -o \( ${BASH_VERSINFO[0]} -eq 5 -a 
${BASH_VERSINFO[1]} -gt 2 \)
-    then
-       sed -ri '/^Ignored:/{ s/(HUP)/\1 INT/ }' tests/expected/kill/decode
-    fi
-fi
 
 %build
 AUTOPOINT=true GTKDOCIZE=true autoreconf -vfi
@@ -628,7 +641,7 @@
 ################
 %if "%ulbuild" == "base"
 %make_install
-mkdir -p "%{buildroot}/%{_distconfdir}/default" 
"%{buildroot}/%{_pam_vendordir}" "%{buildroot}/%{_sysconfdir}/issue.d"
+mkdir -p "%{buildroot}%{_distconfdir}/default" "%{buildroot}%{_pam_vendordir}" 
"%{buildroot}%{_sysconfdir}/issue.d" "%{buildroot}/usr/lib/issue.d"
 install -m 644 %{SOURCE51} %{buildroot}%{_distconfdir}/blkid.conf
 touch %{buildroot}%{_sysconfdir}/blkid.conf
 mkdir %{buildroot}%{_sysconfdir}/blkid.conf.d 
%{buildroot}%{_distconfdir}/blkid.conf.d
@@ -783,6 +796,8 @@
 export TS_OPT_misc_mountpoint_known_fail="yes"
 # This test appears to be racy
 export TS_OPT_lslocks_lslocks_known_fail=yes
+# FIXME: script/options sometimes fails on aarch64, arm7l and s390x
+export TS_OPT_script_options_known_fail=yes
 #
 # hacks
 export PATH="$PATH:/sbin:/usr/sbin"
@@ -894,6 +909,17 @@
 
 %post
 %service_add_post fstrim.service fstrim.timer
+# Migrate from issue-generator. Existed up to SLE16 GA
+if systemctl is-enabled --quiet issue-generator.service ; then
+    rm -f `grep -l '\\\\[46]' /run/issue.d/70-*.conf 2>/dev/null` 2>/dev/null
+    rm -f /run/issue
+fi
+# The old issue layout causes double printing in util-linux >= 2.41. Existed 
up to SLE16 GA
+if test -L /etc/issue ; then
+    if test "`readlink /etc/issue`" = ../run/issue ; then
+        rm /etc/issue
+    fi
+fi
 
 %preun
 %service_del_preun fstrim.service fstrim.timer
@@ -992,6 +1018,7 @@
 # defined no_config
 
 %config %dir %{_sysconfdir}/issue.d
+%dir /usr/lib/issue.d
 %if %{ul_extra_bin_sbin}
 %core /bin/kill
 %core %verify(not mode) %attr(%ul_suid,root,root) /bin/su
@@ -1444,11 +1471,13 @@
 %exclude %{_datadir}/bash-completion/completions/cfdisk
 %exclude %{_datadir}/bash-completion/completions/chcpu
 %exclude %{_datadir}/bash-completion/completions/chmem
+%exclude %{_datadir}/bash-completion/completions/choom
 %exclude %{_datadir}/bash-completion/completions/chrt
 %exclude %{_datadir}/bash-completion/completions/col
 %exclude %{_datadir}/bash-completion/completions/colcrt
 %exclude %{_datadir}/bash-completion/completions/colrm
 %exclude %{_datadir}/bash-completion/completions/column
+%exclude %{_datadir}/bash-completion/completions/coresched
 %exclude %{_datadir}/bash-completion/completions/ctrlaltdel
 %exclude %{_datadir}/bash-completion/completions/delpart
 %exclude %{_datadir}/bash-completion/completions/dmesg

++++++ util-linux-2.41.1.tar.xz -> util-linux-2.41.2.tar.xz ++++++
/work/SRC/openSUSE:Factory/util-linux/util-linux-2.41.1.tar.xz 
/work/SRC/openSUSE:Factory/.util-linux.new.18484/util-linux-2.41.2.tar.xz 
differ: char 15, line 1

++++++ util-linux-agetty-configs.patch ++++++
>From d1cf7efb17869d0fdf132bb3581d9b74a459bb87 Mon Sep 17 00:00:00 2001
From: Stefan Schubert <[email protected]>
Date: Wed, 17 Sep 2025 13:43:55 +0200
Subject: [PATCH 2/8] agetty: using configs lib for parsing issue files

---
 term-utils/agetty.c | 39 +++++++++++++++++++++++----------------
 1 file changed, 23 insertions(+), 16 deletions(-)

Index: util-linux-2.41.2/term-utils/agetty.c
===================================================================
--- util-linux-2.41.2.orig/term-utils/agetty.c
+++ util-linux-2.41.2/term-utils/agetty.c
@@ -122,10 +122,11 @@
 #ifdef SYSV_STYLE
 #  define ISSUE_SUPPORT
 #  if defined(HAVE_SCANDIRAT) && defined(HAVE_OPENAT)
+#    include "configs.h"
 #    include <dirent.h>
 #    define ISSUEDIR_SUPPORT
-#    define ISSUEDIR_EXT       ".issue"
-#    define ISSUEDIR_EXTSIZ    (sizeof(ISSUEDIR_EXT) - 1)
+#    define ISSUEDIR_EXT       "issue"
+#    define ISSUEDIR_EXTSIZ    sizeof(ISSUEDIR_EXT)
 #  endif
 #endif
 
@@ -1683,7 +1684,7 @@ static int issuedir_filter(const struct
 
        namesz = strlen(d->d_name);
        if (!namesz || namesz < ISSUEDIR_EXTSIZ + 1 ||
-           strcmp(d->d_name + (namesz - ISSUEDIR_EXTSIZ), ISSUEDIR_EXT) != 0)
+           strcmp(d->d_name + (namesz - ISSUEDIR_EXTSIZ), "." ISSUEDIR_EXT) != 
0)
                return 0;
 
        /* Accept this */
@@ -1930,22 +1931,28 @@ skip:
                goto done;
        }
 
-       /* The default /etc/issue and optional /etc/issue.d directory as
-        * extension to the file. The /etc/issue.d directory is ignored if
-        * there is no /etc/issue file. The file may be empty or symlink.
+#ifdef         ISSUEDIR_SUPPORT
+       struct list_head file_list;
+       struct list_head *current = NULL;
+       char *name = NULL;
+
+        /* Reading all issue files and concatinating all contents to one 
content.
+         * The ordering rules are defineded in:
+         * 
https://github.com/uapi-group/specifications/blob/main/specs/configuration_files_specification.md
         */
-       if (access(_PATH_ISSUE, F_OK|R_OK) == 0) {
-               issuefile_read(ie, _PATH_ISSUE, op, tp);
-               issuedir_read(ie, _PATH_ISSUEDIR, op, tp);
+       ul_configs_file_list(&file_list,
+                            NULL,
+                            _PATH_ETC_ISSUEDIR,
+                            _PATH_USR_ISSUEDIR,
+                            _PATH_ISSUE_FILENAME,
+                            ISSUEDIR_EXT);
+
+       while (ul_configs_next_filename(&file_list, &current, &name) == 0) {
+               issuefile_read(ie, name, op, tp);
        }
 
-       /* Fallback @runstatedir (usually /run) */
-       issuefile_read(ie, _PATH_RUNSTATEDIR "/" _PATH_ISSUE_FILENAME, op, tp);
-       issuedir_read(ie, _PATH_RUNSTATEDIR "/" _PATH_ISSUE_DIRNAME, op, tp);
-
-       /* Fallback @sysconfstaticdir (usually /usr/lib)*/
-       issuefile_read(ie, _PATH_SYSCONFSTATICDIR "/" _PATH_ISSUE_FILENAME, op, 
tp);
-       issuedir_read(ie, _PATH_SYSCONFSTATICDIR "/" _PATH_ISSUE_DIRNAME, op, 
tp);
+       ul_configs_free_list(&file_list);
+#endif
 
 done:
        if (ie->output) {

++++++ util-linux-agetty-escape-erase.patch ++++++
>From b462fdefe74836c22cb02039dca419a512dc6c88 Mon Sep 17 00:00:00 2001
From: Karel Zak <[email protected]>
Date: Wed, 17 Sep 2025 12:58:59 +0200
Subject: [PATCH] agetty: fix erasure of escape sequences and tab characters

When escape sequences (like arrow keys) or tab characters are entered
at the login prompt, they are properly visualized but only partially
erasable with backspace. This is because the erase logic assumes each
stored character corresponds to one visual character, but escape
sequences display as "^[" (2 chars) and tabs expand to multiple spaces.

Track visual character width for each stored byte in a parallel array.
When erasing, use the stored visual width to properly erase all
displayed characters for that input byte.

Fixes: https://github.com/util-linux/util-linux/issues/3624
Signed-off-by: Karel Zak <[email protected]>
---
 term-utils/agetty.c | 51 ++++++++++++++++++++++++++++++++++++---------
 1 file changed, 41 insertions(+), 10 deletions(-)

diff --git a/term-utils/agetty.c b/term-utils/agetty.c
index 5e564c4f0..c6cb48081 100644
--- a/term-utils/agetty.c
+++ b/term-utils/agetty.c
@@ -2131,20 +2131,30 @@ static void next_speed(struct options *op, struct 
termios *tp)
        tcsetattr(STDIN_FILENO, TCSANOW, tp);
 }
 
+/* Erase visual characters for one stored character */
+static void erase_char(int visual_count, struct chardata *cp)
+{
+       static const char *const erase[] = {    /* backspace-space-backspace */
+               "\010\040\010",         /* space parity */
+               "\010\040\010",         /* odd parity */
+               "\210\240\210",         /* even parity */
+               "\210\240\210",         /* no parity */
+       };
+       int i;
+       for (i = 0; i < visual_count; i++)
+               write_all(1, erase[cp->parity], 3);
+}
+
 /* Get user name, establish parity, speed, erase, kill & eol. */
 static char *get_logname(struct issue *ie, struct options *op, struct termios 
*tp, struct chardata *cp)
 {
        static char logname[BUFSIZ];
+       static int visual_widths[BUFSIZ];       /* visual char count for each 
stored byte */
        char *bp;
+       int *visual_bp;
        char c;                 /* input character, full eight bits */
        char ascval;            /* low 7 bits of input character */
        int eightbit;
-       static const char *const erase[] = {    /* backspace-space-backspace */
-               "\010\040\010",         /* space parity */
-               "\010\040\010",         /* odd parity */
-               "\210\240\210",         /* even parity */
-               "\210\240\210",         /* no parity */
-       };
 
        /* Initialize kill, erase, parity etc. (also after switching speeds). */
        INIT_CHARDATA(cp);
@@ -2158,7 +2168,11 @@ static char *get_logname(struct issue *ie, struct 
options *op, struct termios *t
        tcflush(STDIN_FILENO, TCIFLUSH);
 
        eightbit = (op->flags & (F_EIGHTBITS|F_UTF8));
+
+       /* Initialize buffer pointers. visual_widths tracks how many visual
+        * characters each stored byte represents (e.g. ESC = 2 for "^[", tab = 
1-8 spaces) */
        bp = logname;
+       visual_bp = visual_widths;
        *bp = '\0';
 
        eval_issue_file(ie, op, tp);
@@ -2182,6 +2196,7 @@ static char *get_logname(struct issue *ie, struct options 
*op, struct termios *t
                            && (op->flags & F_NOCLEAR) == 0)
                                termio_clear(STDOUT_FILENO);
                        bp = logname;
+                       visual_bp = visual_widths;
                        *bp = '\0';
                        continue;
                }
@@ -2259,8 +2274,9 @@ static char *get_logname(struct issue *ie, struct options 
*op, struct termios *t
                                cp->erase = ascval; /* set erase character */
                                if (bp > logname) {
                                        if ((tp->c_lflag & ECHO) == 0)
-                                               write_all(1, erase[cp->parity], 
3);
+                                               erase_char(*(visual_bp - 1), 
cp);
                                        bp--;
+                                       visual_bp--;
                                }
                                break;
                        case CTL('U'):
@@ -2272,8 +2288,9 @@ static char *get_logname(struct issue *ie, struct options 
*op, struct termios *t
                                        break;
                                while (bp > logname) {
                                        if ((tp->c_lflag & ECHO) == 0)
-                                               write_all(1, erase[cp->parity], 
3);
+                                               erase_char(*(visual_bp - 1), 
cp);
                                        bp--;
+                                       visual_bp--;
                                }
                                break;
                        case CTL('D'):
@@ -2283,15 +2300,29 @@ static char *get_logname(struct issue *ie, struct 
options *op, struct termios *t
                                        log_err(_("%s: input overrun"), 
op->tty);
                                if ((tp->c_lflag & ECHO) == 0) {
                                        /* Visualize escape sequence instead of 
its execution */
-                                       if (ascval == CTL('['))
+                                       if (ascval == CTL('[')) {
                                                /* Ideally it should be 
"\xe2\x90\x9b"
                                                 * if (op->flags & (F_UTF8)),
                                                 * but only some fonts contain 
it */
                                                write_all(1, "^[", 2);
-                                       else
+                                               *visual_bp = 2;         /* ESC 
shows as ^[ (2 chars) */
+                                       } else if (ascval == '\t') {
+                                               /* Tab expands to spaces */
+                                               int pos = bp - logname;
+                                               int spaces = 8 - (pos % 8);
+                                               int i;
+                                               for (i = 0; i < spaces; i++)
+                                                       write_all(1, " ", 1);
+                                               *visual_bp = spaces;
+                                       } else {
                                                write_all(1, &c, 1);    /* echo 
the character */
+                                               *visual_bp = 1;         /* 
normal char shows as 1 */
+                                       }
+                               } else {
+                                       *visual_bp = 1;         /* when echo is 
on, assume 1 char */
                                }
                                *bp++ = ascval;                 /* and store it 
*/
+                               visual_bp++;
                                break;
                        }
                        /* Everything was erased. */
-- 
2.48.1


++++++ util-linux-agetty-netlink-fix4.patch ++++++
>From fa9b5740f67bc64d7b58f9b2fcc4f2883d7dcc91 Mon Sep 17 00:00:00 2001
From: Stanislav Brabec <[email protected]>
Date: Fri, 10 Oct 2025 13:17:26 +0200
Subject: [PATCH 6/6] agetty: Process all data from ul_nl_process()

However select() normally triggers immediately after a partial read, it does not
happen for netlink socket. It keeps unprocessed data until the next netlink
message appears. It causes raising processing delays.

Always read all data. It also potentially decreases number of issue redraws.

Signed-off-by: Stanislav Brabec <[email protected]>
---
 include/netlink.h   |  6 +++++-
 term-utils/agetty.c | 14 +++++++++++---
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/include/netlink.h b/include/netlink.h
index 3d7c3da04..ee4917b39 100644
--- a/include/netlink.h
+++ b/include/netlink.h
@@ -40,7 +40,9 @@
                             * reach unprocessed NLMSG_DONE */
 #define        UL_NL_SOFT_ERROR 4  /* soft error, indicating a race condition 
or
                             * message relating to events before program
-                            * start); could be optionally ignored */
+                            * start); could be optionally ignored and it
+                            * should not considered as a reason to leave the
+                            * processing */
 
 struct ul_nl_data;
 
@@ -139,6 +141,8 @@ int ul_nl_request_dump(struct ul_nl_data *nl, uint16_t 
nlmsg_type);
 /* Process netlink messages.
  * async: If true, return UL_NL_WOULDBLOCK immediately if there is no data
  *   ready. If false, wait for a message.
+ *   NOTE: You should read all data until you get UL_NL_WOULDBLOCK, otherwise
+ *         select() will not trigger even if there is a netlink message.
  * loop: If true, run in a loop until NLMSG_DONE is received. Returns after
  *   finishing a reply from ul_nl_request_dump(), otherwise it acts as an
  *   infinite loop. If false, it returns after processing one message.
diff --git a/term-utils/agetty.c b/term-utils/agetty.c
index ec922bd11..08d009261 100644
--- a/term-utils/agetty.c
+++ b/term-utils/agetty.c
@@ -1654,9 +1654,17 @@ static int wait_for_term_input(struct issue *ie, int fd)
                }
 
                if (ie->nl.fd >= 0 && FD_ISSET(ie->nl.fd, &rfds)) {
-                       /* We are ignoring errors here to prevent unability of
-                        * further processing. */
-                       ul_nl_process(&(ie->nl), UL_NL_ASYNC, UL_NL_ONESHOT);
+                       int rc;
+
+                       /* We are looping until it returns UL_NL_WOULDBLOCK.
+                        * To prevent infinite loop, we are leaving on any other
+                        * error except UL_NL_SOFT_ERROR. To prevent unability
+                        * of further processing, we never exit. */
+                       do {
+                               rc = ul_nl_process(&(ie->nl), UL_NL_ASYNC,
+                                                  UL_NL_ONESHOT);
+                       }
+                       while (!rc || rc == UL_NL_SOFT_ERROR);
 
                /* Just drain the inotify buffer */
                } else if (inotify_fd >= 0 && FD_ISSET(inotify_fd, &rfds)) {
-- 
2.48.1


++++++ util-linux-agetty-netlink.patch ++++++
--- /var/tmp/diff_new_pack.slZcAX/_old  2025-10-18 14:36:48.219881080 +0200
+++ /var/tmp/diff_new_pack.slZcAX/_new  2025-10-18 14:36:48.219881080 +0200
@@ -1,7 +1,7 @@
-From bf7c46ef9158f3baae6b637ebb73a24d8460d394 Mon Sep 17 00:00:00 2001
+From b8b5030d792c0ffe51ee4a5925d43735b5d782d8 Mon Sep 17 00:00:00 2001
 From: Stanislav Brabec <[email protected]>
 Date: Wed, 9 Jul 2025 14:35:28 +0200
-Subject: [PATCH 2/2] agetty: Implement netlink based IP processing
+Subject: [PATCH 2/6] agetty: Implement netlink based IP processing
 
 The current \4 and \6 issue file escapes implementation is inferior. It
 uses get getifaddrs() to get a list of IP addresses. This function does not
@@ -50,11 +50,11 @@
  term-utils/agetty.c      | 417 ++++++++++++++++++++++-----------------
  2 files changed, 246 insertions(+), 177 deletions(-)
 
-diff --git a/term-utils/agetty.8.adoc b/term-utils/agetty.8.adoc
-index a33f12a3f..6670498f5 100644
---- a/term-utils/agetty.8.adoc
-+++ b/term-utils/agetty.8.adoc
-@@ -253,6 +253,12 @@ Insert the IPv4 address of the specified network 
interface (for example: \4\{eth
+Index: util-linux-2.41.2/term-utils/agetty.8.adoc
+===================================================================
+--- util-linux-2.41.2.orig/term-utils/agetty.8.adoc
++++ util-linux-2.41.2/term-utils/agetty.8.adoc
+@@ -247,6 +247,12 @@ Insert the IPv4 address of the specified
  6 or 6{_interface_}::
  The same as \4 but for IPv6.
  
@@ -67,10 +67,10 @@
  b::
  Insert the baudrate of the current line.
  
-diff --git a/term-utils/agetty.c b/term-utils/agetty.c
-index 5e564c4f0..c37417e1e 100644
---- a/term-utils/agetty.c
-+++ b/term-utils/agetty.c
+Index: util-linux-2.41.2/term-utils/agetty.c
+===================================================================
+--- util-linux-2.41.2.orig/term-utils/agetty.c
++++ util-linux-2.41.2/term-utils/agetty.c
 @@ -32,10 +32,7 @@
  #include <langinfo.h>
  #include <grp.h>
@@ -226,7 +226,7 @@
  
                /* Just drain the inotify buffer */
                } else if (inotify_fd >= 0 && FD_ISSET(inotify_fd, &rfds)) {
-@@ -1937,11 +1865,44 @@ static void eval_issue_file(struct issue *ie,
+@@ -1937,11 +1865,44 @@ static void eval_issue_file(struct issue
                            struct options *op,
                            struct termios *tp)
  {
@@ -274,7 +274,7 @@
        /*
         * The custom issue file or directory list specified by:
         *   agetty --issue-file <path[:path]...>
-@@ -1986,11 +1947,6 @@ static void eval_issue_file(struct issue *ie,
+@@ -1986,11 +1947,6 @@ static void eval_issue_file(struct issue
        issuedir_read(ie, _PATH_SYSCONFSTATICDIR "/" _PATH_ISSUE_DIRNAME, op, 
tp);
  
  done:
@@ -317,7 +317,7 @@
                        }
                }
  #endif
-@@ -2168,7 +2130,7 @@ static char *get_logname(struct issue *ie, struct 
options *op, struct termios *t
+@@ -2168,7 +2130,7 @@ static char *get_logname(struct issue *i
  
        no_reload:
  #ifdef AGETTY_RELOAD
@@ -326,7 +326,7 @@
                        /* refresh prompt -- discard input data, clear terminal
                         * and call do_prompt() again
                         */
-@@ -2177,6 +2139,8 @@ static char *get_logname(struct issue *ie, struct 
options *op, struct termios *t
+@@ -2177,6 +2139,8 @@ static char *get_logname(struct issue *i
                        eval_issue_file(ie, op, tp);
                        if (!issue_is_changed(ie))
                                goto no_reload;
@@ -335,41 +335,27 @@
                        tcflush(STDIN_FILENO, TCIFLUSH);
                        if ((op->flags & F_VCONSOLE)
                            && (op->flags & F_NOCLEAR) == 0)
-@@ -2576,92 +2540,170 @@ static void log_warn(const char *fmt, ...)
+@@ -2576,92 +2540,170 @@ static void log_warn(const char *fmt, ..
        va_end(ap);
  }
  
 -static void print_addr(struct issue *ie, sa_family_t family, void *addr)
+-{
+-      char buff[INET6_ADDRSTRLEN + 1];
 +static void print_iface_best(struct issue *ie,
 +                           const char *ifname,
 +                           uint8_t ifa_family)
- {
--      char buff[INET6_ADDRSTRLEN + 1];
++{
 +      struct ul_netaddrq_ip *best[__ULNETLINK_RATING_MAX];
 +      struct ul_netaddrq_iface *ifaceq;
 +      struct list_head *l;
 +      enum ul_netaddrq_ip_rating threshold;
- 
--      inet_ntop(family, addr, buff, sizeof(buff));
--      fprintf(ie->output, "%s", buff);
--}
++
 +      if (!ie->nl.data_addr)
 +              return; /* error: init failed */
  
--/*
-- * Prints IP for the specified interface (@iface), if the interface is not
-- * specified then prints the "best" one (UP, RUNNING, non-LOOPBACK). If not
-- * found the "best" interface then prints at least host IP.
-- */
--static void output_iface_ip(struct issue *ie,
--                          struct ifaddrs *addrs,
--                          const char *iface,
--                          sa_family_t family)
--{
--      struct ifaddrs *p;
--      struct addrinfo hints, *info = NULL;
--      char *host = NULL;
--      void *addr = NULL;
+-      inet_ntop(family, addr, buff, sizeof(buff));
+-      fprintf(ie->output, "%s", buff);
 +      if ((ifaceq = ul_netaddrq_iface_by_name(&(ie->nl), ifname)))
 +      {
 +              memset(best, 0, sizeof(best));
@@ -378,18 +364,29 @@
 +              else
 +              /* if (ifa_family == AF_INET6) */
 +                      l = &(ifaceq->ip_quality_list_6);
- 
--      if (!addrs)
--              return;
++
 +              threshold =
 +                      ul_netaddrq_iface_bestaddr(l, &best);
 +              if (best[threshold])
 +                      fputs(ul_nl_addr_ntop_address(best[threshold]->addr),
 +                            ie->output);
 +      }
-+}
+ }
  
--      for (p = addrs; p; p = p->ifa_next) {
+-/*
+- * Prints IP for the specified interface (@iface), if the interface is not
+- * specified then prints the "best" one (UP, RUNNING, non-LOOPBACK). If not
+- * found the "best" interface then prints at least host IP.
+- */
+-static void output_iface_ip(struct issue *ie,
+-                          struct ifaddrs *addrs,
+-                          const char *iface,
+-                          sa_family_t family)
+-{
+-      struct ifaddrs *p;
+-      struct addrinfo hints, *info = NULL;
+-      char *host = NULL;
+-      void *addr = NULL;
 +static void print_addrq_bestofall(struct issue *ie,
 +                                uint8_t ifa_family)
 +{
@@ -397,38 +394,22 @@
 +      enum ul_netaddrq_ip_rating threshold;
 +      const char *best_ipp;
  
--              if (!p->ifa_name ||
--                  !p->ifa_addr ||
--                  p->ifa_addr->sa_family != family)
--                      continue;
+-      if (!addrs)
+-              return;
 +      if (!ie->nl.data_addr)
 +              return; /* error: init failed */
  
--              if (iface) {
--                      /* Filter out by interface name */
--                     if (strcmp(p->ifa_name, iface) != 0)
--                              continue;
--              } else {
--                      /* Select the "best" interface */
--                      if ((p->ifa_flags & IFF_LOOPBACK) ||
--                          !(p->ifa_flags & IFF_UP) ||
--                          !(p->ifa_flags & IFF_RUNNING))
--                              continue;
--              }
+-      for (p = addrs; p; p = p->ifa_next) {
 +      best_ipp = ul_netaddrq_get_best_ipp(&(ie->nl), ifa_family,
 +                                          &threshold, &best_ifaceq);
 +      if (best_ipp)
 +              fputs(best_ipp, ie->output);
 +}
  
--              addr = NULL;
--              switch (p->ifa_addr->sa_family) {
--              case AF_INET:
--                      addr = &((struct sockaddr_in *) p->ifa_addr)->sin_addr;
--                      break;
--              case AF_INET6:
--                      addr = &((struct sockaddr_in6 *) 
p->ifa_addr)->sin6_addr;
--                      break;
+-              if (!p->ifa_name ||
+-                  !p->ifa_addr ||
+-                  p->ifa_addr->sa_family != family)
+-                      continue;
 +static void dump_iface_good(struct issue *ie,
 +                          struct ul_netaddrq_iface *ifaceq)
 +{
@@ -438,7 +419,18 @@
 +      enum ul_netaddrq_ip_rating threshold = __ULNETLINK_RATING_MAX - 1;
 +      enum ul_netaddrq_ip_rating fthreshold; /* per family threshold */
 +      bool first = true;
-+
+ 
+-              if (iface) {
+-                      /* Filter out by interface name */
+-                     if (strcmp(p->ifa_name, iface) != 0)
+-                              continue;
+-              } else {
+-                      /* Select the "best" interface */
+-                      if ((p->ifa_flags & IFF_LOOPBACK) ||
+-                          !(p->ifa_flags & IFF_UP) ||
+-                          !(p->ifa_flags & IFF_RUNNING))
+-                              continue;
+-              }
 +      memset(best4, 0, sizeof(best4));
 +      threshold = ul_netaddrq_iface_bestaddr(&(ifaceq->ip_quality_list_4),
 +                                             &best4);
@@ -447,11 +439,23 @@
 +                                              &best6);
 +      if (fthreshold < threshold)
 +              threshold = fthreshold;
-+
+ 
+-              addr = NULL;
+-              switch (p->ifa_addr->sa_family) {
+-              case AF_INET:
+-                      addr = &((struct sockaddr_in *) p->ifa_addr)->sin_addr;
+-                      break;
+-              case AF_INET6:
+-                      addr = &((struct sockaddr_in6 *) 
p->ifa_addr)->sin6_addr;
+-                      break;
+-              }
 +      list_for_each(li, &(ifaceq->ip_quality_list_4))
 +      {
 +              struct ul_netaddrq_ip *ipq;
-+
+ 
+-              if (addr) {
+-                      print_addr(ie, family, addr);
+-                      return;
 +              ipq = list_entry(li, struct ul_netaddrq_ip, entry);
 +              if (threshold <= ULNETLINK_RATING_SCOPE_LINK &&
 +                  ( ipq->quality <= threshold ||
@@ -478,15 +482,29 @@
 +                                    ie->output);
                }
 +      temp_cont4:;
-+      }
+       }
  
--              if (addr) {
--                      print_addr(ie, family, addr);
--                      return;
+-      if (iface)
+-              return;
+-
+-      /* Hmm.. not found the best interface, print host IP at least */
+-      memset(&hints, 0, sizeof(hints));
+-      hints.ai_family = family;
+-      if (family == AF_INET6)
+-              hints.ai_flags = AI_V4MAPPED;
 +      list_for_each(li, &(ifaceq->ip_quality_list_6))
 +      {
 +              struct ul_netaddrq_ip *ipq;
-+
+ 
+-      host = xgethostname();
+-      if (host && getaddrinfo(host, NULL, &hints, &info) == 0 && info) {
+-              switch (info->ai_family) {
+-              case AF_INET:
+-                      addr = &((struct sockaddr_in *) 
info->ai_addr)->sin_addr;
+-                      break;
+-              case AF_INET6:
+-                      addr = &((struct sockaddr_in6 *) 
info->ai_addr)->sin6_addr;
+-                      break;
 +              ipq = list_entry(li, struct ul_netaddrq_ip, entry);
 +              if (threshold <= ULNETLINK_RATING_SCOPE_LINK &&
 +                  ( ipq->quality <= threshold ||
@@ -512,36 +530,22 @@
 +                              fputs(ul_nl_addr_ntop_address(ipq->addr),
 +                                    ie->output);
                }
+-              if (addr)
+-                      print_addr(ie, family, addr);
 +      temp_cont6:;
-       }
++      }
 +      if (!first)
 +              fputs("\n", ie->output);
 +}
  
--      if (iface)
--              return;
+-              freeaddrinfo(info);
 +static void dump_iface_all(struct issue *ie,
 +                         struct ul_netaddrq_iface *ifaceq)
 +{
 +      struct list_head *li;
 +      struct ul_netaddrq_ip *ipq;
 +      bool first = true;
- 
--      /* Hmm.. not found the best interface, print host IP at least */
--      memset(&hints, 0, sizeof(hints));
--      hints.ai_family = family;
--      if (family == AF_INET6)
--              hints.ai_flags = AI_V4MAPPED;
--
--      host = xgethostname();
--      if (host && getaddrinfo(host, NULL, &hints, &info) == 0 && info) {
--              switch (info->ai_family) {
--              case AF_INET:
--                      addr = &((struct sockaddr_in *) 
info->ai_addr)->sin_addr;
--                      break;
--              case AF_INET6:
--                      addr = &((struct sockaddr_in6 *) 
info->ai_addr)->sin6_addr;
--                      break;
++
 +      list_for_each(li, &(ifaceq->ip_quality_list_4))
 +      {
 +              ipq = list_entry(li, struct ul_netaddrq_ip, entry);
@@ -549,11 +553,7 @@
 +              {
 +                      fprintf(ie->output, "%s: ", ifaceq->ifname);
 +                      first = false;
-               }
--              if (addr)
--                      print_addr(ie, family, addr);
--
--              freeaddrinfo(info);
++              }
 +              else
 +                      fprintf(ie->output, " ");
 +              fputs(ul_nl_addr_ntop_address(ipq->addr), ie->output);
@@ -576,7 +576,7 @@
  }
  
  /*
-@@ -2860,26 +2902,47 @@ static void output_special_char(struct issue *ie,
+@@ -2860,26 +2902,47 @@ static void output_special_char(struct i
        case '4':
        case '6':
        {
@@ -634,7 +634,4 @@
  #endif
        default:
                putc(c, ie->output);
--- 
-2.48.1
-
 

++++++ util-linux-lib-configs-fix1.patch ++++++
>From 16826c6675df3b6b28851c72f2dd1d194d3c7189 Mon Sep 17 00:00:00 2001
From: Stefan Schubert <[email protected]>
Date: Wed, 1 Oct 2025 12:19:08 +0200
Subject: [PATCH 3/8] Using fix issue dir path "/usr/lib" for agetty

---
 include/pathnames.h | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/include/pathnames.h b/include/pathnames.h
index 298d94973..80a0ee00a 100644
--- a/include/pathnames.h
+++ b/include/pathnames.h
@@ -73,11 +73,7 @@
 
 #define _PATH_ISSUE_FILENAME   "issue"
 #define _PATH_ETC_ISSUEDIR     "/etc"
-#ifdef USE_VENDORDIR
-#  define _PATH_USR_ISSUEDIR   _PATH_VENDORDIR
-#else
-#  define _PATH_USR_ISSUEDIR   "/usr/lib"
-#endif
+#define _PATH_USR_ISSUEDIR     "/usr/lib"
 
 #define _PATH_OS_RELEASE_ETC   "/etc/os-release"
 #define _PATH_OS_RELEASE_USR   "/usr/lib/os-release"
-- 
2.48.1


++++++ util-linux-lib-configs-fix2.patch ++++++
>From a7f5e5c9f9c00823e04e89e9030337239a5bd7b8 Mon Sep 17 00:00:00 2001
From: Karel Zak <[email protected]>
Date: Wed, 1 Oct 2025 14:42:39 +0200
Subject: [PATCH 4/8] agetty: use standard path macros

- remove unnecessary issuefile-related stuff from include/pathnames.h
- use standard _PATH_* macros

Signed-off-by: Karel Zak <[email protected]>
---
 include/pathnames.h |  4 ----
 lib/configs.c       |  4 +---
 term-utils/agetty.c | 10 ++++++----
 3 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/include/pathnames.h b/include/pathnames.h
index 80a0ee00a..036f365fd 100644
--- a/include/pathnames.h
+++ b/include/pathnames.h
@@ -71,10 +71,6 @@
 # define _PATH_BTMP            "/var/log/btmp"
 #endif
 
-#define _PATH_ISSUE_FILENAME   "issue"
-#define _PATH_ETC_ISSUEDIR     "/etc"
-#define _PATH_USR_ISSUEDIR     "/usr/lib"
-
 #define _PATH_OS_RELEASE_ETC   "/etc/os-release"
 #define _PATH_OS_RELEASE_USR   "/usr/lib/os-release"
 #define _PATH_NUMLOCK_ON       _PATH_RUNSTATEDIR "/numlock-on"
diff --git a/lib/configs.c b/lib/configs.c
index b038844d2..0534c18ef 100644
--- a/lib/configs.c
+++ b/lib/configs.c
@@ -16,8 +16,6 @@
 #include "list.h"
 #include "fileutils.h"
 
-#define DEFAULT_ETC_SUBDIR "/etc"
-
 struct file_element {
        struct list_head file_list;
        char *filename;
@@ -212,7 +210,7 @@ int ul_configs_file_list(struct list_head *file_list,
 
        /* Default is /etc */
        if (!etc_subdir)
-               etc_subdir = DEFAULT_ETC_SUBDIR;
+               etc_subdir = _PATH_SYSCONFDIR;
 
        if (!usr_subdir)
                usr_subdir = "";
diff --git a/term-utils/agetty.c b/term-utils/agetty.c
index 3e0a4ec4f..31dbf2706 100644
--- a/term-utils/agetty.c
+++ b/term-utils/agetty.c
@@ -1969,7 +1969,7 @@ static void eval_issue_file(struct issue *ie,
                goto done;
        }
 
-#ifdef         ISSUEDIR_SUPPORT
+#ifdef ISSUEDIR_SUPPORT
        struct list_head file_list;
        struct list_head *current = NULL;
        char *name = NULL;
@@ -1977,12 +1977,14 @@ static void eval_issue_file(struct issue *ie,
         /* Reading all issue files and concatinating all contents to one 
content.
          * The ordering rules are defineded in:
          * 
https://github.com/uapi-group/specifications/blob/main/specs/configuration_files_specification.md
+        *
+        * Note that _PATH_RUNSTATEDIR (/run) is always read by 
ul_configs_file_list().
         */
        ul_configs_file_list(&file_list,
                             NULL,
-                            _PATH_ETC_ISSUEDIR,
-                            _PATH_USR_ISSUEDIR,
-                            _PATH_ISSUE_FILENAME,
+                            _PATH_SYSCONFDIR,
+                            _PATH_SYSCONFSTATICDIR,
+                            "issue",
                             ISSUEDIR_EXT);
 
        while (ul_configs_next_filename(&file_list, &current, &name) == 0) {
-- 
2.48.1


++++++ util-linux-lib-configs-fix3.patch ++++++
>From dc1e88ff93f40f2f8093fcf35bda615a9384edcd Mon Sep 17 00:00:00 2001
From: Karel Zak <[email protected]>
Date: Wed, 1 Oct 2025 14:39:01 +0200
Subject: [PATCH 5/8] build-sys: make sure _PATH_SYSCONFDIR is defined

The autotools and meson define $sysconfdir, but this variable is not
accessible for compiler. Fix it.

Signed-off-by: Karel Zak <[email protected]>
---
 Makefile.am | 1 +
 meson.build | 1 +
 2 files changed, 2 insertions(+)

diff --git a/Makefile.am b/Makefile.am
index 01e99701d..dd78a5345 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,6 +4,7 @@ AM_CPPFLAGS = \
        -DLOCALEDIR=\"$(localedir)\" \
        -D_PATH_RUNSTATEDIR=\"${runstatedir}\" \
        -D_PATH_LOCALSTATEDIR=\"${localstatedir}\" \
+       -D_PATH_SYSCONFDIR=\"${sysconfdir}\" \
        -D_PATH_SYSCONFSTATICDIR=\"${sysconfstaticdir}\"
 
 if USE_VENDORDIR
diff --git a/meson.build b/meson.build
index c9d1e188e..cdaca47ee 100644
--- a/meson.build
+++ b/meson.build
@@ -73,6 +73,7 @@ conf.set('sysconfdir', sysconfdir)
 conf.set('usrbin_execdir', usrbin_exec_dir)
 conf.set('usrsbin_execdir', usrsbin_exec_dir)
 conf.set('docdir', docdir)
+conf.set_quoted('_PATH_SYSCONFDIR', sysconfdir)
 conf.set_quoted('_PATH_SYSCONFSTATICDIR', sysconfstaticdir)
 conf.set_quoted('_PATH_RUNSTATEDIR', runstatedir)
 conf.set_quoted('_PATH_LOCALSTATEDIR', localstatedir)
-- 
2.48.1


++++++ util-linux-lib-configs-fix4.patch ++++++
>From 03066584f148a8429386c4a928d093913b3e85e2 Mon Sep 17 00:00:00 2001
From: Karel Zak <[email protected]>
Date: Wed, 1 Oct 2025 14:53:41 +0200
Subject: [PATCH 6/8] lib/configs: improve readability

Signed-off-by: Karel Zak <[email protected]>
---
 include/configs.h |  5 +++--
 lib/configs.c     | 16 ++++++++++------
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/include/configs.h b/include/configs.h
index 783c10e30..ea72afacc 100644
--- a/include/configs.h
+++ b/include/configs.h
@@ -3,7 +3,8 @@
  * it what you wish.
  *
  * Evaluting a list of configuration filenames which have to be handled/parsed.
- * The order of this file list has been defined by 
+ *
+ * The order of this file list has been defined by
  * 
https://github.com/uapi-group/specifications/blob/main/specs/configuration_files_specification.md
  */
 
@@ -89,4 +90,4 @@ int ul_configs_next_filename(struct list_head *file_list,
                             struct list_head **current_entry,
                             char **name);
 
-#endif
+#endif /* UTIL_LINUX_CONFIGS_H */
diff --git a/lib/configs.c b/lib/configs.c
index 0534c18ef..a5d714f23 100644
--- a/lib/configs.c
+++ b/lib/configs.c
@@ -12,6 +12,7 @@
 #if defined(HAVE_SCANDIRAT) && defined(HAVE_OPENAT)
 #include <dirent.h>
 #endif
+
 #include "configs.h"
 #include "list.h"
 #include "fileutils.h"
@@ -21,8 +22,8 @@ struct file_element {
        char *filename;
 };
 
-/* Checking for main configuration file 
- * 
+/* Checking for main configuration file
+ *
  * Returning absolute path or NULL if not found
  * The return value has to be freed by the caller.
  */
@@ -34,7 +35,7 @@ static char *main_configs(const char *root,
        bool found = false;
        char *path = NULL;
        struct stat st;
-       
+
        if (config_suffix) {
                if (asprintf(&path, "%s/%s/%s.%s", root, project, config_name, 
config_suffix) < 0)
                        return NULL;
@@ -179,7 +180,7 @@ finish:
        return counter;
 }
 
-#endif
+#endif /* HAVE_SCANDIRAT */
 
 static void free_list_entry(struct file_element *element)
 {
@@ -187,7 +188,6 @@ static void free_list_entry(struct file_element *element)
        free(element);
 }
 
-
 int ul_configs_file_list(struct list_head *file_list,
                         const char *project,
                         const char *etc_subdir,
@@ -201,7 +201,7 @@ int ul_configs_file_list(struct list_head *file_list,
        struct list_head *etc_entry = NULL, *usr_entry = NULL;
        struct file_element *add_element = NULL, *usr_element = NULL, 
*etc_element = NULL;
        int counter = 0;
-       
+
        INIT_LIST_HEAD(file_list);
 
        if (!config_name){
@@ -256,11 +256,15 @@ int ul_configs_file_list(struct list_head *file_list,
 #endif
 
        list_for_each(etc_entry, &etc_file_list) {
+
                etc_element = list_entry(etc_entry, struct file_element, 
file_list);
                etc_basename = ul_basename(etc_element->filename);
+
                list_for_each(usr_entry, &usr_file_list) {
+
                        usr_element = list_entry(usr_entry, struct 
file_element, file_list);
                        usr_basename = ul_basename(usr_element->filename);
+
                        if (strcmp(usr_basename, etc_basename) <= 0) {
                                if (strcmp(usr_basename, etc_basename) < 0) {
                                        add_element = 
new_list_entry(usr_element->filename);
-- 
2.48.1


++++++ util-linux-lib-configs-fix5.patch ++++++
>From ec71160db85acde32a9eca5fb238c82d6a6e52cb Mon Sep 17 00:00:00 2001
From: Karel Zak <[email protected]>
Date: Thu, 2 Oct 2025 11:55:55 +0200
Subject: [PATCH 7/8] lib/configs: initialize FD to -1

Signed-off-by: Karel Zak <[email protected]>
---
 lib/configs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/configs.c b/lib/configs.c
index a5d714f23..d40743198 100644
--- a/lib/configs.c
+++ b/lib/configs.c
@@ -107,7 +107,7 @@ static int read_dir(struct list_head *file_list,
        char *dirname = NULL;
        char *filename = NULL;
        struct stat st;
-       int dd = 0, nfiles = 0, i;
+       int dd = -1, nfiles = 0, i;
        int counter = 0;
        struct dirent **namelist = NULL;
        struct file_element *entry = NULL;
@@ -175,7 +175,7 @@ finish:
                free(namelist[i]);
        free(namelist);
        free(dirname);
-       if (dd > 0)
+       if (dd >= 0)
                close(dd);
        return counter;
 }
-- 
2.48.1


++++++ util-linux-lib-configs-fix6.patch ++++++
>From 6e723400a384c39f0df709b17af43e51c0a4f505 Mon Sep 17 00:00:00 2001
From: Stefan Schubert <[email protected]>
Date: Tue, 7 Oct 2025 17:24:37 +0200
Subject: [PATCH 8/8] parsing /run/issue.d/* too

---
 lib/configs.c | 82 ++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 72 insertions(+), 10 deletions(-)

diff --git a/lib/configs.c b/lib/configs.c
index d40743198..09bfffb66 100644
--- a/lib/configs.c
+++ b/lib/configs.c
@@ -195,11 +195,15 @@ int ul_configs_file_list(struct list_head *file_list,
                         const char *config_name,
                         const char *config_suffix)
 {
-       char *filename = NULL, *usr_basename = NULL, *etc_basename = NULL;
+       char *filename = NULL, *run_basename = NULL, *usr_basename = NULL,
+               *etc_basename = NULL, *etc_run_basename = NULL;
        struct list_head etc_file_list;
+       struct list_head run_file_list;
+       struct list_head etc_run_file_list;
        struct list_head usr_file_list;
-       struct list_head *etc_entry = NULL, *usr_entry = NULL;
-       struct file_element *add_element = NULL, *usr_element = NULL, 
*etc_element = NULL;
+       struct list_head *etc_entry = NULL, *usr_entry = NULL, *run_entry = 
NULL, *etc_run_entry = NULL;
+       struct file_element *add_element = NULL, *usr_element = NULL,
+               *run_element = NULL, *etc_element = NULL, *etc_run_element = 
NULL;
        int counter = 0;
 
        INIT_LIST_HEAD(file_list);
@@ -235,38 +239,94 @@ int ul_configs_file_list(struct list_head *file_list,
        }
 
        INIT_LIST_HEAD(&etc_file_list);
+       INIT_LIST_HEAD(&run_file_list);
+       INIT_LIST_HEAD(&etc_run_file_list);
        INIT_LIST_HEAD(&usr_file_list);
 
 #if defined(HAVE_SCANDIRAT) && defined(HAVE_OPENAT)
-       int ret_usr = 0, ret_etc = 0;
+       int ret_usr = 0, ret_etc = 0, ret_run = 0;
         ret_etc = read_dir(&etc_file_list,
                           project,
                           etc_subdir,
                           config_name,
                           config_suffix);
+       ret_run = read_dir(&run_file_list,
+                          project,
+                          _PATH_RUNSTATEDIR,
+                          config_name,
+                          config_suffix);
        ret_usr = read_dir(&usr_file_list,
                           project,
                           usr_subdir,
                           config_name,
                           config_suffix);
-       if (ret_etc == -ENOMEM || ret_usr == -ENOMEM) {
+       if (ret_etc == -ENOMEM || ret_usr == -ENOMEM || ret_run == -ENOMEM) {
                counter = -ENOMEM;
                goto finish;
        }
 #endif
 
+       /* Merging run and etc list in the correct order. Output: etc_run_list 
*/
        list_for_each(etc_entry, &etc_file_list) {
 
                etc_element = list_entry(etc_entry, struct file_element, 
file_list);
                etc_basename = ul_basename(etc_element->filename);
 
+               list_for_each(run_entry, &run_file_list) {
+
+                       run_element = list_entry(run_entry, struct 
file_element, file_list);
+                       run_basename = ul_basename(run_element->filename);
+
+                       if (strcmp(run_basename, etc_basename) <= 0) {
+                               if (strcmp(run_basename, etc_basename) < 0) {
+                                       add_element = 
new_list_entry(run_element->filename);
+                                       if (add_element == NULL) {
+                                               counter = -ENOMEM;
+                                               goto finish;
+                                       }
+                                       list_add_tail(&add_element->file_list, 
&etc_run_file_list);
+                                       counter++;
+                               }
+                               list_del(&run_element->file_list);
+                       } else {
+                               break;
+                       }
+               }
+               add_element = new_list_entry(etc_element->filename);
+               if (add_element == NULL) {
+                       counter = -ENOMEM;
+                       goto finish;
+               }
+               list_add_tail(&add_element->file_list, &etc_run_file_list);
+               counter++;
+       }
+
+       /* taking the rest of /run */
+       list_for_each(run_entry, &run_file_list) {
+               run_element = list_entry(run_entry, struct file_element, 
file_list);
+               add_element = new_list_entry(run_element->filename);
+               if (add_element == NULL) {
+                       counter = -ENOMEM;
+                       goto finish;
+               }
+               list_add_tail(&add_element->file_list, &etc_run_file_list);
+               counter++;
+       }
+
+       /* Merging etc_run list and var list in the correct order. Output: 
file_list
+          which will be returned. */
+       list_for_each(etc_run_entry, &etc_run_file_list) {
+
+               etc_run_element = list_entry(etc_run_entry, struct 
file_element, file_list);
+               etc_run_basename = ul_basename(etc_run_element->filename);
+
                list_for_each(usr_entry, &usr_file_list) {
 
                        usr_element = list_entry(usr_entry, struct 
file_element, file_list);
                        usr_basename = ul_basename(usr_element->filename);
 
-                       if (strcmp(usr_basename, etc_basename) <= 0) {
-                               if (strcmp(usr_basename, etc_basename) < 0) {
+                       if (strcmp(usr_basename, etc_run_basename) <= 0) {
+                               if (strcmp(usr_basename, etc_run_basename) < 0) 
{
                                        add_element = 
new_list_entry(usr_element->filename);
                                        if (add_element == NULL) {
                                                counter = -ENOMEM;
@@ -280,7 +340,7 @@ int ul_configs_file_list(struct list_head *file_list,
                                break;
                        }
                }
-               add_element = new_list_entry(etc_element->filename);
+               add_element = new_list_entry(etc_run_element->filename);
                if (add_element == NULL) {
                        counter = -ENOMEM;
                        goto finish;
@@ -303,6 +363,7 @@ int ul_configs_file_list(struct list_head *file_list,
 
 finish:
        ul_configs_free_list(&etc_file_list);
+       ul_configs_free_list(&etc_run_file_list);
        ul_configs_free_list(&usr_file_list);
 
        return counter;
@@ -319,11 +380,12 @@ int ul_configs_next_filename(struct list_head *file_list,
 {
        struct file_element *element = NULL;
 
-       if (*current_entry == file_list)
+       if (list_empty(file_list) || *current_entry == file_list)
                return 1;
 
        if (*current_entry == NULL)
-               *current_entry = file_list;
+               *current_entry = file_list->next;
+
        element = list_entry(*current_entry, struct file_element, file_list);
        *name = element->filename;
        *current_entry = (*current_entry)->next;
-- 
2.48.1


++++++ util-linux-lib-configs.patch ++++++
>From 4109f4bfefff9e6cd65815399af3eab2b0a59104 Mon Sep 17 00:00:00 2001
From: Stefan Schubert <[email protected]>
Date: Wed, 17 Sep 2025 13:40:29 +0200
Subject: [PATCH 1/8] libcommon: added lib "configs" for parsing configuration
 files in the correct order

---
 include/Makemodule.am |   3 +-
 include/configs.h     |  92 ++++++++++++
 include/pathnames.h   |  10 +-
 lib/Makemodule.am     |   3 +-
 lib/configs.c         | 330 ++++++++++++++++++++++++++++++++++++++++++
 lib/meson.build       |   1 +
 6 files changed, 433 insertions(+), 6 deletions(-)
 create mode 100644 include/configs.h
 create mode 100644 lib/configs.c

diff --git a/include/Makemodule.am b/include/Makemodule.am
index 59ecc793f..bc2c73415 100644
--- a/include/Makemodule.am
+++ b/include/Makemodule.am
@@ -83,4 +83,5 @@ dist_noinst_HEADERS += \
        include/ttyutils.h \
        include/widechar.h \
        include/xalloc.h \
-       include/xxhash.h
+       include/xxhash.h \
+       include/configs.h
diff --git a/include/configs.h b/include/configs.h
new file mode 100644
index 000000000..783c10e30
--- /dev/null
+++ b/include/configs.h
@@ -0,0 +1,92 @@
+/*
+ * No copyright is claimed.  This code is in the public domain; do with
+ * it what you wish.
+ *
+ * Evaluting a list of configuration filenames which have to be handled/parsed.
+ * The order of this file list has been defined by 
+ * 
https://github.com/uapi-group/specifications/blob/main/specs/configuration_files_specification.md
+ */
+
+#ifndef UTIL_LINUX_CONFIGS_H
+#define UTIL_LINUX_CONFIGS_H
+
+#include "list.h"
+
+/**
+ * ul_configs_file_list - Evaluting a list of sorted configuration filenames 
which have to be handled
+ *                        in the correct order.
+ *
+ * @file_list: List of filenames which have to be parsed in that order
+ * @project: name of the project used as subdirectory, can be NULL
+ * @etc_subdir: absolute directory path for user changed configuration files, 
can be NULL (default "/etc").
+ * @usr_subdir: absolute directory path of vendor defined settings (often 
"/usr/lib").
+ * @config_name: basename of the configuration file. If it is NULL, drop-ins 
without a main configuration file will be parsed only. 
+ * @config_suffix: suffix of the configuration file. Can also be NULL.
+ *
+ * Returns the length of the file_list, or -ENOMEM, or -ENOTEMPTY if 
config_name is NULL
+ *
+ * Example:
+ * int count = 0;
+ * struct list_head *file_list;
+ *
+ * count = ul_configs_file_list(&file_list,
+ *                              "foo",
+ *                              "/etc",
+ *                              "/usr/lib",
+ *                              "example",
+ *                              "conf");
+ *
+ * The order of this file list has been defined by
+ * 
https://github.com/uapi-group/specifications/blob/main/specs/configuration_files_specification.md
+ *
+ */
+int ul_configs_file_list(struct list_head *file_list,
+                        const char *project,
+                        const char *etc_subdir,
+                        const char *usr_subdir,
+                        const char *config_name,
+                        const char *config_suffix);
+
+
+/**
+ * ul_configs_free_list - Freeing configuration list.
+ *
+ * @file_list: List of filenames which has to be freed.
+ *
+ */
+void ul_configs_free_list(struct list_head *file_list);
+
+
+/**
+ * ul_configs_next_filename - Going through the file list which has to be 
handled/parsed.
+ *
+ * @file_list: List of filenames which have to be handled.
+ * @current_entry: Current list entry. Has to be initialized with NULL for the 
first call.
+ * @name: Returned file name for each call.
+ *
+ * Returns 0 on success, <0 on error and 1 if the end of the list has been 
reached.
+ *
+ * Example:
+ * int count = 0;
+ * struct list_head *file_list = NULL;
+ * struct list_head *current = NULL;
+ * char *name = NULL;
+ *
+ * count = ul_configs_file_list(&file_list,
+ *                              "foo",
+ *                              "/etc",
+ *                              "/usr/lib",
+ *                              "example",
+ *                              "conf");
+ *
+ * while (ul_configs_next_filename(&file_list, &current, &name) == 0)
+ *       printf("filename: %s\n", name);
+ *
+ * ul_configs_free_list(&file_list);
+ *
+ */
+int ul_configs_next_filename(struct list_head *file_list,
+                            struct list_head **current_entry,
+                            char **name);
+
+#endif
diff --git a/include/pathnames.h b/include/pathnames.h
index 0f9944f89..298d94973 100644
--- a/include/pathnames.h
+++ b/include/pathnames.h
@@ -72,10 +72,12 @@
 #endif
 
 #define _PATH_ISSUE_FILENAME   "issue"
-#define _PATH_ISSUE_DIRNAME    _PATH_ISSUE_FILENAME ".d"
-
-#define _PATH_ISSUE            "/etc/" _PATH_ISSUE_FILENAME
-#define _PATH_ISSUEDIR         "/etc/" _PATH_ISSUE_DIRNAME
+#define _PATH_ETC_ISSUEDIR     "/etc"
+#ifdef USE_VENDORDIR
+#  define _PATH_USR_ISSUEDIR   _PATH_VENDORDIR
+#else
+#  define _PATH_USR_ISSUEDIR   "/usr/lib"
+#endif
 
 #define _PATH_OS_RELEASE_ETC   "/etc/os-release"
 #define _PATH_OS_RELEASE_USR   "/usr/lib/os-release"
diff --git a/lib/Makemodule.am b/lib/Makemodule.am
index a60810d7d..84ab3e3ae 100644
--- a/lib/Makemodule.am
+++ b/lib/Makemodule.am
@@ -40,7 +40,8 @@ libcommon_la_SOURCES = \
        lib/strv.c \
        lib/timeutils.c \
        lib/ttyutils.c \
-       lib/xxhash.c
+       lib/xxhash.c \
+       lib/configs.c
 
 if LINUX
 libcommon_la_SOURCES += \
diff --git a/lib/configs.c b/lib/configs.c
new file mode 100644
index 000000000..b038844d2
--- /dev/null
+++ b/lib/configs.c
@@ -0,0 +1,330 @@
+/*
+ * configs_file.c instantiates functions defined and described in 
configs_file.h
+ */
+#include <err.h>
+#include <errno.h>
+#include <sys/syslog.h>
+#include <sys/stat.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#if defined(HAVE_SCANDIRAT) && defined(HAVE_OPENAT)
+#include <dirent.h>
+#endif
+#include "configs.h"
+#include "list.h"
+#include "fileutils.h"
+
+#define DEFAULT_ETC_SUBDIR "/etc"
+
+struct file_element {
+       struct list_head file_list;
+       char *filename;
+};
+
+/* Checking for main configuration file 
+ * 
+ * Returning absolute path or NULL if not found
+ * The return value has to be freed by the caller.
+ */
+static char *main_configs(const char *root,
+                         const char *project,
+                         const char *config_name,
+                         const char *config_suffix)
+{
+       bool found = false;
+       char *path = NULL;
+       struct stat st;
+       
+       if (config_suffix) {
+               if (asprintf(&path, "%s/%s/%s.%s", root, project, config_name, 
config_suffix) < 0)
+                       return NULL;
+               if (stat(path, &st) == 0) {
+                       found = true;
+               } else {
+                       free(path);
+                       path = NULL;
+               }
+       }
+       if (!found) {
+               /* trying filename without suffix */
+               if (asprintf(&path, "%s/%s/%s", root, project, config_name) < 0)
+                       return NULL;
+               if (stat(path, &st) != 0) {
+                       /* not found */
+                       free(path);
+                       path = NULL;
+               }
+       }
+       return path;
+}
+
+static struct file_element *new_list_entry(const char *filename)
+{
+       struct file_element *file_element = calloc(1, sizeof(*file_element));
+
+       if (file_element == NULL)
+               return NULL;
+
+       INIT_LIST_HEAD(&file_element->file_list);
+
+       if (filename != NULL) {
+               file_element->filename = strdup(filename);
+               if (file_element->filename == NULL) {
+                       free(file_element);
+                       return NULL;
+               }
+       } else {
+               file_element->filename = NULL;
+       }
+
+       return file_element;
+}
+
+#if defined(HAVE_SCANDIRAT) && defined(HAVE_OPENAT)
+
+static int filter(const struct dirent *d)
+{
+#ifdef _DIRENT_HAVE_D_TYPE
+       if (d->d_type != DT_UNKNOWN && d->d_type != DT_REG &&
+           d->d_type != DT_LNK)
+               return 0;
+#endif
+       if (*d->d_name == '.')
+               return 0;
+
+       /* Accept this */
+       return 1;
+}
+
+static int read_dir(struct list_head *file_list,
+                   const char *project,
+                   const char *root,
+                   const char *config_name,
+                   const char *config_suffix)
+{
+       bool found = false;
+       char *dirname = NULL;
+       char *filename = NULL;
+       struct stat st;
+       int dd = 0, nfiles = 0, i;
+       int counter = 0;
+       struct dirent **namelist = NULL;
+       struct file_element *entry = NULL;
+
+       if (config_suffix) {
+               if (asprintf(&dirname, "%s/%s/%s.%s.d",
+                            root, project, config_name, config_suffix) < 0)
+                       return -ENOMEM;
+               if (stat(dirname, &st) == 0) {
+                       found = true;
+               } else {
+                       free(dirname);
+                       dirname = NULL;
+               }
+       }
+       if (!found) {
+               /* trying path without suffix */
+               if (asprintf(&dirname, "%s/%s/%s.d", root, project, 
config_name) < 0)
+                       return -ENOMEM;
+               if (stat(dirname, &st) != 0) {
+                       /* not found */
+                       free(dirname);
+                       dirname = NULL;
+               }
+       }
+
+       if (dirname==NULL)
+               goto finish;
+
+       dd = open(dirname, O_RDONLY|O_CLOEXEC|O_DIRECTORY);
+       if (dd < 0)
+               goto finish;
+
+       nfiles = scandirat(dd, ".", &namelist, filter, alphasort);
+       if (nfiles <= 0)
+               goto finish;
+
+       for (i = 0; i < nfiles; i++) {
+               struct dirent *d = namelist[i];
+               size_t namesz = strlen(d->d_name);
+               if (config_suffix && strlen(config_suffix) > 0 &&
+                   (!namesz || namesz < strlen(config_suffix) + 1 ||
+                    strcmp(d->d_name + (namesz - strlen(config_suffix)), 
config_suffix) != 0)) {
+                       /* filename does not have requested suffix */
+                       continue;
+               }
+
+               if (asprintf(&filename, "%s/%s", dirname, d->d_name) < 0) {
+                       counter = -ENOMEM;
+                       break;
+               }
+               entry = new_list_entry(filename);
+               free(filename);
+               if (entry == NULL) {
+                       counter = -ENOMEM;
+                       break;
+               }
+
+               list_add_tail(&entry->file_list, file_list);
+               counter++;
+       }
+
+finish:
+       for (i = 0; i < nfiles; i++)
+               free(namelist[i]);
+       free(namelist);
+       free(dirname);
+       if (dd > 0)
+               close(dd);
+       return counter;
+}
+
+#endif
+
+static void free_list_entry(struct file_element *element)
+{
+       free(element->filename);
+       free(element);
+}
+
+
+int ul_configs_file_list(struct list_head *file_list,
+                        const char *project,
+                        const char *etc_subdir,
+                        const char *usr_subdir,
+                        const char *config_name,
+                        const char *config_suffix)
+{
+       char *filename = NULL, *usr_basename = NULL, *etc_basename = NULL;
+       struct list_head etc_file_list;
+       struct list_head usr_file_list;
+       struct list_head *etc_entry = NULL, *usr_entry = NULL;
+       struct file_element *add_element = NULL, *usr_element = NULL, 
*etc_element = NULL;
+       int counter = 0;
+       
+       INIT_LIST_HEAD(file_list);
+
+       if (!config_name){
+               return -ENOTEMPTY;
+       }
+
+       /* Default is /etc */
+       if (!etc_subdir)
+               etc_subdir = DEFAULT_ETC_SUBDIR;
+
+       if (!usr_subdir)
+               usr_subdir = "";
+
+       if (!project)
+               project = "";
+
+       /* Evaluating first "main" file which has to be parsed */
+       /* in the following order : /etc /run /usr             */
+       filename = main_configs(etc_subdir, project, config_name, 
config_suffix);
+       if (filename == NULL)
+               filename = main_configs(_PATH_RUNSTATEDIR, project, 
config_name, config_suffix);
+       if (filename == NULL)
+               filename = main_configs(usr_subdir, project, config_name, 
config_suffix);
+       if (filename != NULL) {
+               add_element = new_list_entry(filename);
+               free(filename);
+               if (add_element == NULL)
+                       return -ENOMEM;
+               list_add_tail(&add_element->file_list, file_list);
+               counter++;
+       }
+
+       INIT_LIST_HEAD(&etc_file_list);
+       INIT_LIST_HEAD(&usr_file_list);
+
+#if defined(HAVE_SCANDIRAT) && defined(HAVE_OPENAT)
+       int ret_usr = 0, ret_etc = 0;
+        ret_etc = read_dir(&etc_file_list,
+                          project,
+                          etc_subdir,
+                          config_name,
+                          config_suffix);
+       ret_usr = read_dir(&usr_file_list,
+                          project,
+                          usr_subdir,
+                          config_name,
+                          config_suffix);
+       if (ret_etc == -ENOMEM || ret_usr == -ENOMEM) {
+               counter = -ENOMEM;
+               goto finish;
+       }
+#endif
+
+       list_for_each(etc_entry, &etc_file_list) {
+               etc_element = list_entry(etc_entry, struct file_element, 
file_list);
+               etc_basename = ul_basename(etc_element->filename);
+               list_for_each(usr_entry, &usr_file_list) {
+                       usr_element = list_entry(usr_entry, struct 
file_element, file_list);
+                       usr_basename = ul_basename(usr_element->filename);
+                       if (strcmp(usr_basename, etc_basename) <= 0) {
+                               if (strcmp(usr_basename, etc_basename) < 0) {
+                                       add_element = 
new_list_entry(usr_element->filename);
+                                       if (add_element == NULL) {
+                                               counter = -ENOMEM;
+                                               goto finish;
+                                       }
+                                       list_add_tail(&add_element->file_list, 
file_list);
+                                       counter++;
+                               }
+                               list_del(&usr_element->file_list);
+                       } else {
+                               break;
+                       }
+               }
+               add_element = new_list_entry(etc_element->filename);
+               if (add_element == NULL) {
+                       counter = -ENOMEM;
+                       goto finish;
+               }
+               list_add_tail(&add_element->file_list, file_list);
+               counter++;
+       }
+
+       /* taking the rest of /usr */
+       list_for_each(usr_entry, &usr_file_list) {
+               usr_element = list_entry(usr_entry, struct file_element, 
file_list);
+               add_element = new_list_entry(usr_element->filename);
+               if (add_element == NULL) {
+                       counter = -ENOMEM;
+                       goto finish;
+               }
+               list_add_tail(&add_element->file_list, file_list);
+               counter++;
+       }
+
+finish:
+       ul_configs_free_list(&etc_file_list);
+       ul_configs_free_list(&usr_file_list);
+
+       return counter;
+}
+
+void ul_configs_free_list(struct list_head *file_list)
+{
+       list_free(file_list, struct file_element,  file_list, free_list_entry);
+}
+
+int ul_configs_next_filename(struct list_head *file_list,
+                            struct list_head **current_entry,
+                            char **name)
+{
+       struct file_element *element = NULL;
+
+       if (*current_entry == file_list)
+               return 1;
+
+       if (*current_entry == NULL)
+               *current_entry = file_list;
+       element = list_entry(*current_entry, struct file_element, file_list);
+       *name = element->filename;
+       *current_entry = (*current_entry)->next;
+
+       return 0;
+}
diff --git a/lib/meson.build b/lib/meson.build
index d62af238b..70e2703d5 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -29,6 +29,7 @@ lib_common_sources = '''
        timeutils.c
        ttyutils.c
        xxhash.c
+       configs.c
 '''.split()
 
 idcache_c = files('idcache.c')
-- 
2.48.1


++++++ util-linux-lib-netlink-fix1.patch ++++++
>From a5db8d0a9ed63969381feeee1eb0c3b39d32876b Mon Sep 17 00:00:00 2001
From: Stanislav Brabec <[email protected]>
Date: Sun, 5 Oct 2025 02:29:00 +0200
Subject: [PATCH 3/6] ul_nl_addr_dup(): Fix address comparison

When duplicating struct ul_nl_addr, set address to ifa_local, if it is set
to ifa_local in the source. This fixes the address for PtP IPv4 network
interfaces and avoids UL_NL_SOFT_ERROR during address removal.

Signed-off-by: Stanislav Brabec <[email protected]>
---
 lib/netlink.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/netlink.c b/lib/netlink.c
index 3def42e50..f8ac2c4c8 100644
--- a/lib/netlink.c
+++ b/lib/netlink.c
@@ -328,7 +328,7 @@ int ul_nl_close(struct ul_nl_data *nl) {
        return close(nl->fd);
 }
 
-struct ul_nl_addr *ul_nl_addr_dup (struct ul_nl_addr *addr) {
+struct ul_nl_addr *ul_nl_addr_dup(struct ul_nl_addr *addr) {
        struct ul_nl_addr *newaddr;
        newaddr = calloc(1, sizeof(struct ul_nl_addr));
        if (!newaddr)
@@ -348,7 +348,7 @@ struct ul_nl_addr *ul_nl_addr_dup (struct ul_nl_addr *addr) 
{
                memcpy(newaddr->ifa_local, addr->ifa_local,
                       addr->ifa_local_len);
        }
-       if (&(addr->ifa_address) == &(addr->ifa_local))
+       if (addr->address == addr->ifa_local)
                newaddr->address = newaddr->ifa_local;
        else
                newaddr->address = newaddr->ifa_address;
@@ -360,7 +360,7 @@ error:
        return NULL;
 }
 
-void ul_nl_addr_free (struct ul_nl_addr *addr) {
+void ul_nl_addr_free(struct ul_nl_addr *addr) {
        if (addr) {
                free(addr->ifa_address);
                free(addr->ifa_local);
-- 
2.48.1


++++++ util-linux-lib-netlink-fix2.patch ++++++
>From 030303e4b93b65a5172a0c80f9f864b06f76cb81 Mon Sep 17 00:00:00 2001
From: Stanislav Brabec <[email protected]>
Date: Sun, 5 Oct 2025 02:53:17 +0200
Subject: [PATCH 4/6] netlink process_addr(): Ignore UL_NL_SOFT_ERROR

UL_NL_SOFT_ERROR can be issued if kernel sends unpaired RTM_DELADDR. It
should not happen, but it can happen due to race condition. And it happened
in some kernel versions. It is not reason to exit the processing loop.

Signed-off-by: Stanislav Brabec <[email protected]>
---
 lib/netlink.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/lib/netlink.c b/lib/netlink.c
index f8ac2c4c8..3e58e17da 100644
--- a/lib/netlink.c
+++ b/lib/netlink.c
@@ -130,7 +130,9 @@ static int process_addr(struct ul_nl_data *nl, struct 
nlmsghdr *nh)
                nl->addr.ifname = ifname;
        else
        {
-               /* There can be race, we do not return error here */
+               /* There can be race, we do not return error here.
+                * It also happens on RTM_DELADDR, as interface name could
+                * disappear from kernel tables before we process it. */
                /* FIXME I18N: *"unknown"* is too generic. Use context. */
                /* TRANSLATORS: unknown network interface, maximum 15
                 * (IF_NAMESIZE-1) bytes */
@@ -289,7 +291,8 @@ int ul_nl_process(struct ul_nl_data *nl, bool async, bool 
loop)
                                    ul_debugobj(nl,
                                                "process_msg() returned %d",
                                                rc));
-                               return rc;
+                               if (rc != UL_NL_SOFT_ERROR)
+                                       return rc;
                        }
                }
                if (!loop)
-- 
2.48.1


++++++ util-linux-lib-netlink-fix3.patch ++++++
>From 60c5c0516e6ce52863b12343a1cd276423ab3bae Mon Sep 17 00:00:00 2001
From: Stanislav Brabec <[email protected]>
Date: Wed, 8 Oct 2025 01:14:32 +0200
Subject: [PATCH 5/6] netaddrq: Fix crash if there are no IP addresses

If there are no IP addresses, ul_netaddrq_bestaddr() returns threshold
ULNETLINK_RATING_BAD, but there were no addresses in the best array, and
best_ifaceq remains unset, which caused crash. Setting the initial
threshold to __ULNETLINK_RATING_MAX and checking for that value fixes that.
And more, it also allows to accept IP addresses with ULNETLINK_RATING_BAD
rating.

Signed-off-by: Stanislav Brabec <[email protected]>
---
 include/netaddrq.h  | 14 ++++++++++----
 lib/netaddrq.c      | 10 +++++-----
 term-utils/agetty.c |  2 +-
 3 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/include/netaddrq.h b/include/netaddrq.h
index 6d5e655f5..d9c595f32 100644
--- a/include/netaddrq.h
+++ b/include/netaddrq.h
@@ -94,8 +94,11 @@ ul_netaddrq_iface_bestaddr(struct list_head *ipq_list,
  *   best_iface: interface where the best address was seen
  *   best array: best ifa_valid lifetime seen per quality rating
  *   return value: best rating seen
- * Note: It can be needed to call it twice: once for ip_quality_list_4, once
- * for ip_quality_list_6.
+ * Notes:
+ * - It can be needed to call it twice: once for ip_quality_list_4, once
+ *   for ip_quality_list_6.
+ * - If no IP addresses are found, the function can return
+ *   _ULNETLINK_RATING_MAX!
  */
 enum ul_netaddrq_ip_rating
 ul_netaddrq_bestaddr(struct ul_nl_data *nl,
@@ -109,8 +112,11 @@ ul_netaddrq_bestaddr(struct ul_nl_data *nl,
  *   return value: The best address as a string
  *   threshold: The best rating ever seen.
  *   best_ifaceq: The best rated interfece ever seen.
- * Note: It can be needed to call it twice: once for AF_INET, once
- * for AF_INET6.
+ * Notes:
+ * - It can be needed to call it twice: once for AF_INET, once
+ *   for AF_INET6.
+ * - If the return value is NULL (i. e. there are no usable interfaces), then
+ *   *best_ifaceq remains unchanges and cannot be used.
  */
 const char *ul_netaddrq_get_best_ipp(struct ul_nl_data *nl,
                                     uint8_t ifa_family,
diff --git a/lib/netaddrq.c b/lib/netaddrq.c
index 34431d8d3..1ce454aaf 100644
--- a/lib/netaddrq.c
+++ b/lib/netaddrq.c
@@ -296,7 +296,7 @@ ul_netaddrq_iface_bestaddr(struct list_head *ipq_list,
        struct ul_netaddrq_ip *ipq;
        enum ul_netaddrq_ip_rating threshold;
 
-       threshold = ULNETLINK_RATING_BAD;
+       threshold = __ULNETLINK_RATING_MAX;
        list_for_each(li, ipq_list)
        {
                ipq = list_entry(li, struct ul_netaddrq_ip, entry);
@@ -342,7 +342,7 @@ ul_netaddrq_bestaddr(struct ul_nl_data *nl,
                ipqo = offsetof(struct ul_netaddrq_iface, ip_quality_list_6);
        }
 
-       threshold = ULNETLINK_RATING_BAD;
+       threshold = __ULNETLINK_RATING_MAX;
        list_for_each(li, &(addrq->ifaces))
        {
                struct list_head *ipq_list;
@@ -374,7 +374,7 @@ const char *ul_netaddrq_get_best_ipp(struct ul_nl_data *nl,
 
        memset(best, 0, sizeof(best));
        *threshold = ul_netaddrq_bestaddr(nl, best_ifaceq, &best, ifa_family);
-       if (best[*threshold])
+       if (*threshold != __ULNETLINK_RATING_MAX)
                return ul_nl_addr_ntop_address(best[*threshold]->addr);
        return NULL;
 }
@@ -423,7 +423,7 @@ static void dump_iface_best(struct ul_nl_data *nl,
        memset(best, 0, sizeof(best));
        threshold = ul_netaddrq_iface_bestaddr(&(ifaceq->ip_quality_list_4),
                                               &best);
-       if (best[threshold])
+       if (threshold != __ULNETLINK_RATING_MAX)
        {
                fprintf(netout, "%s IPv4: %s", (first ? "best address" : " "),
                       ul_nl_addr_ntop_address(best[threshold]->addr));
@@ -432,7 +432,7 @@ static void dump_iface_best(struct ul_nl_data *nl,
        memset(best, 0, sizeof(best));
        threshold = ul_netaddrq_iface_bestaddr(&(ifaceq->ip_quality_list_6),
                                               &best);
-       if (best[threshold])
+       if (threshold != __ULNETLINK_RATING_MAX)
        {
                fprintf(netout, "%s IPv6: %s", (first ? "best address" : " "),
                       ul_nl_addr_ntop_address(best[threshold]->addr));
diff --git a/term-utils/agetty.c b/term-utils/agetty.c
index b7786ce7d..ec922bd11 100644
--- a/term-utils/agetty.c
+++ b/term-utils/agetty.c
@@ -2603,7 +2603,7 @@ static void print_iface_best(struct issue *ie,
 
                threshold =
                        ul_netaddrq_iface_bestaddr(l, &best);
-               if (best[threshold])
+               if (threshold != __ULNETLINK_RATING_MAX)
                        fputs(ul_nl_addr_ntop_address(best[threshold]->addr),
                              ie->output);
        }
-- 
2.48.1


++++++ util-linux-lib-netlink.patch ++++++
--- /var/tmp/diff_new_pack.slZcAX/_old  2025-10-18 14:36:48.363887104 +0200
+++ /var/tmp/diff_new_pack.slZcAX/_new  2025-10-18 14:36:48.367887271 +0200
@@ -1,7 +1,7 @@
-From 02b917ba6fa43908a39f15c9496de04910044c0e Mon Sep 17 00:00:00 2001
+From ee8586cbdfb20bea6b1a7e3f10f136b6c8554f02 Mon Sep 17 00:00:00 2001
 From: Stanislav Brabec <[email protected]>
 Date: Wed, 9 Jul 2025 14:29:10 +0200
-Subject: [PATCH 1/2] New netlink library
+Subject: [PATCH 1/6] New netlink library
 
 To support netlink and IP address processing, two new library files were
 added:
@@ -21,18 +21,18 @@
  include/netlink.h     | 171 ++++++++++
  lib/Makemodule.am     |  11 +
  lib/meson.build       |   2 +
- lib/netaddrq.c        | 716 ++++++++++++++++++++++++++++++++++++++++++
- lib/netlink.c         | 465 +++++++++++++++++++++++++++
- 7 files changed, 1491 insertions(+)
+ lib/netaddrq.c        | 723 ++++++++++++++++++++++++++++++++++++++++++
+ lib/netlink.c         | 466 +++++++++++++++++++++++++++
+ 7 files changed, 1499 insertions(+)
  create mode 100644 include/netaddrq.h
  create mode 100644 include/netlink.h
  create mode 100644 lib/netaddrq.c
  create mode 100644 lib/netlink.c
 
-diff --git a/include/Makemodule.am b/include/Makemodule.am
-index bdf87e221..4e310f0c4 100644
---- a/include/Makemodule.am
-+++ b/include/Makemodule.am
+Index: util-linux-2.41.2/include/Makemodule.am
+===================================================================
+--- util-linux-2.41.2.orig/include/Makemodule.am
++++ util-linux-2.41.2/include/Makemodule.am
 @@ -48,6 +48,8 @@ dist_noinst_HEADERS += \
        include/monotonic.h \
        include/mount-api-utils.h \
@@ -42,11 +42,10 @@
        include/nls.h \
        include/optutils.h \
        include/pager.h \
-diff --git a/include/netaddrq.h b/include/netaddrq.h
-new file mode 100644
-index 000000000..6d5e655f5
+Index: util-linux-2.41.2/include/netaddrq.h
+===================================================================
 --- /dev/null
-+++ b/include/netaddrq.h
++++ util-linux-2.41.2/include/netaddrq.h
 @@ -0,0 +1,124 @@
 +/*
 + * Netlink address quality rating list builder
@@ -172,11 +171,10 @@
 +                                                  const char *ifname);
 +
 +#endif /* UTIL_LINUX_NETADDRQ_H */
-diff --git a/include/netlink.h b/include/netlink.h
-new file mode 100644
-index 000000000..3d7c3da04
+Index: util-linux-2.41.2/include/netlink.h
+===================================================================
 --- /dev/null
-+++ b/include/netlink.h
++++ util-linux-2.41.2/include/netlink.h
 @@ -0,0 +1,171 @@
 +/*
 + * Netlink message processing
@@ -349,10 +347,10 @@
 +   ul_nl_addr_ntop(addr, UL_NL_ADDR_IFA_LOCAL)
 +
 +#endif /* UTIL_LINUX_NETLINK_H */
-diff --git a/lib/Makemodule.am b/lib/Makemodule.am
-index bf24b6bee..4af6589d1 100644
---- a/lib/Makemodule.am
-+++ b/lib/Makemodule.am
+Index: util-linux-2.41.2/lib/Makemodule.am
+===================================================================
+--- util-linux-2.41.2.orig/lib/Makemodule.am
++++ util-linux-2.41.2/lib/Makemodule.am
 @@ -1,4 +1,5 @@
  #
 +
@@ -377,7 +375,7 @@
        test_randutils \
        test_remove_env \
        test_strutils \
-@@ -138,6 +143,12 @@ test_ismounted_LDADD = libcommon.la $(LDADD)
+@@ -138,6 +143,12 @@ test_ismounted_LDADD = libcommon.la $(LD
  test_mangle_SOURCES = lib/mangle.c
  test_mangle_CFLAGS = $(AM_CFLAGS) -DTEST_PROGRAM_MANGLE
  
@@ -390,10 +388,10 @@
  test_strutils_SOURCES = lib/strutils.c
  test_strutils_CFLAGS = $(AM_CFLAGS) -DTEST_PROGRAM_STRUTILS
  
-diff --git a/lib/meson.build b/lib/meson.build
-index 25febbc19..8734108a3 100644
---- a/lib/meson.build
-+++ b/lib/meson.build
+Index: util-linux-2.41.2/lib/meson.build
+===================================================================
+--- util-linux-2.41.2.orig/lib/meson.build
++++ util-linux-2.41.2/lib/meson.build
 @@ -17,6 +17,8 @@ lib_common_sources = '''
        mbsalign.c
        mbsedit.c
@@ -403,12 +401,11 @@
        procfs.c
        pwdutils.c
        randutils.c
-diff --git a/lib/netaddrq.c b/lib/netaddrq.c
-new file mode 100644
-index 000000000..67a43cb85
+Index: util-linux-2.41.2/lib/netaddrq.c
+===================================================================
 --- /dev/null
-+++ b/lib/netaddrq.c
-@@ -0,0 +1,716 @@
++++ util-linux-2.41.2/lib/netaddrq.c
+@@ -0,0 +1,723 @@
 +/*
 + * Netlink address quality rating list builder
 + *
@@ -542,6 +539,7 @@
 +
 +      list_for_each(li, &(addrq->ifaces)) {
 +              struct ul_netaddrq_iface *ifaceqq;
++
 +              ifaceqq = list_entry(li, struct ul_netaddrq_iface, entry);
 +              if (ifaceqq->ifa_index == nl->addr.ifa_index) {
 +                      ifaceq = ifaceqq;
@@ -571,9 +569,9 @@
 +                      if (!(ifaceq->ifname = strdup(nl->addr.ifname)))
 +                      {
 +                              DBG(LIST, ul_debugobj(addrq,
-+                                                     "malloc() 2 failed"));
++                                                    "malloc() failed"));
 +                              free(ifaceq);
-+                              return -1;
++                              return -ENOMEM;
 +                      }
 +                      list_add_tail(&(ifaceq->entry), &(addrq->ifaces));
 +                      DBG(LIST, ul_debugobj(ifaceq,
@@ -595,11 +593,17 @@
 +      }
 +
 +      list_for_each(li, ipq_list) {
-+              ipq = list_entry(li, struct ul_netaddrq_ip, entry);
-+              if (ipq->addr->address_len == nl->addr.address_len)
-+                      if (!memcmp(ipq->addr->address, nl->addr.address,
-+                                 nl->addr.address_len))
++              struct ul_netaddrq_ip *ipqq;
++
++              ipqq = list_entry(li, struct ul_netaddrq_ip, entry);
++              if (ipqq->addr->address_len == nl->addr.address_len)
++                      if (!memcmp(ipqq->addr->address, nl->addr.address,
++                                 nl->addr.address_len)) {
++                              ipq = ipqq;
++                              DBG(LIST, ul_debugobj(ipq,
++                                                    "address found in 
ipq_list"));
 +                              break;
++                      }
 +      }
 +      if (ipq == NULL) {
 +                      DBG(LIST, ul_debugobj(ipq_list,
@@ -1125,12 +1129,11 @@
 +      return rc;
 +}
 +#endif /* TEST_PROGRAM_NETADDRQ */
-diff --git a/lib/netlink.c b/lib/netlink.c
-new file mode 100644
-index 000000000..fbe04dd4c
+Index: util-linux-2.41.2/lib/netlink.c
+===================================================================
 --- /dev/null
-+++ b/lib/netlink.c
-@@ -0,0 +1,465 @@
++++ util-linux-2.41.2/lib/netlink.c
+@@ -0,0 +1,466 @@
 +/*
 + * Netlink message processing
 + *
@@ -1149,6 +1152,7 @@
 +#include <sys/socket.h>
 +#include <arpa/inet.h>
 +#include <netinet/in.h>
++#include "strutils.h"
 +#include "netlink.h"
 +#include "debug.h"
 +#include "nls.h"
@@ -1501,7 +1505,7 @@
 +      }
 +}
 +
-+const char *ul_nl_addr_ntop (const struct ul_nl_addr *addr, int addrid) {
++const char *ul_nl_addr_ntop(const struct ul_nl_addr *addr, int addrid) {
 +      const void **ifa_addr = (const void **)((const char *)addr + addrid);
 +      /* (INET6_ADDRSTRLEN-1) + (IF_NAMESIZE-1) + strlen("%") + 1 */
 +      static char addr_str[INET6_ADDRSTRLEN+IF_NAMESIZE];
@@ -1519,7 +1523,7 @@
 +                      p = addr_str;
 +                      while (*p) p++;
 +                      *p++ = '%';
-+                      strncpy(p, addr->ifname, IF_NAMESIZE);
++                      xstrncpy(p, addr->ifname, IF_NAMESIZE);
 +                      return addr_str;
 +              } else
 +                      return inet_ntop(AF_INET6,
@@ -1596,7 +1600,4 @@
 +      return rc;
 +}
 +#endif /* TEST_PROGRAM_NETLINK */
--- 
-2.48.1
-
 

++++++ util-linux-man-generated.patch ++++++
Index: util-linux-2.41.2/term-utils/agetty.8
===================================================================
--- util-linux-2.41.2.orig/term-utils/agetty.8
+++ util-linux-2.41.2/term-utils/agetty.8
@@ -456,6 +458,16 @@ Insert the IPv4 address of the specified
 The same as \(rs4 but for IPv6.
 .RE
 .sp
+a
+.RS 4
+Insert list of "good" IP addresses for all interfaces. It prints best 
candidates for remote login IP addresses: global and site addresses; if not 
available, temporary address with the longest lifetime, if not available, link 
address. Note that link addresses are printed with local interface name, but 
they has to be done with the interface name on the machine where they will be 
used.
+.RE
+.sp
+A
+.RS 4
+Insert list of all IP addresses for all interfaces.
+.RE
+.sp
 b
 .RS 4
 Insert the baudrate of the current line.

Reply via email to