Bug#1143030: netkit-ntalk: FTBFS on hurd-amd64: PATH_MAX and MAXHOSTNAMELEN undeclared

Federico Bonino <[email protected]> Wed, 29 Jul 2026 20:32:40 +0000
Newsgroups gmane.linux.debian.qa-packages
Message-ID <CAE6APk6tcB8sQqxO92PDQR9a36J_VL1+5RX=TBkmjJzFDvSdgw__46579.2091142916$1785357331$gmane$org@mail.gmail.com>
--00000000000007e9a90657c5df21
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Source: netkit-ntalk
Version: 0.17-20
Severity: important
Tags: patch, ftbfs
User: [email protected]
Usertags: hurd-amd64
X-Debbugs-Cc: [email protected]

netkit-ntalk fails to build from source on hurd-amd64 because two macros
the source relies on are not defined by the Hurd libc headers:

Buildd log (hurd-amd64, 0.17-20):
https://buildd.debian.org/status/fetch.php?pkg=3Dnetkit-ntalk&arch=3Dhurd-a=
md64&ver=3D0.17-20&stamp=3D1783711377&raw=3D1

  talk/get_names.c:55:23: error: 'MAXHOSTNAMELEN' undeclared (first use in
this function)
     55 |         char hostname[MAXHOSTNAMELEN];

The build stops there. One file later, talkd/process.c:122 declares
find_user()'s scratch buffer as "char besttty[PATH_MAX]", which does not
compile on Hurd either.

Root cause: GNU/Hurd has no fixed path limit, so PATH_MAX is not defined.
MAXHOSTNAMELEN is a BSD constant that is also absent on Hurd.

The patch below replaces the PATH_MAX-sized temporary buffer in
talkd/process.c with dynamic allocation. It also supplies MAXHOSTNAMELEN
from HOST_NAME_MAX, or from _POSIX_HOST_NAME_MAX when HOST_NAME_MAX is
unavailable. No feature or test is disabled.

I verified the patch on native GNU/Hurd amd64 running Debian unstable. The
unmodified 0.17-20 source reproduced the MAXHOSTNAMELEN build failure. The
patch then applied with zero fuzz and zero offset, and dpkg-buildpackage
completed successfully, producing talk and talkd. The package defines no
autopkgtest or upstream test suite.

One thing to flag rather than let you find it in your own build log: on GCC
15 the new strdup(uptr->ut_line) call raises

  warning: 'strdup' argument 1 declared attribute 'nonstring'
[-Wstringop-overread]

because ut_line is a fixed-size utmp field with no guaranteed NUL
terminator.
The strcpy() it replaces read ut_line exactly the same way, so this is a
new diagnostic rather than a new unbounded read =E2=80=94 but it is new, an=
d it
appears on every architecture. If you would prefer the variant without it,
sizing besttty
as sizeof(uptr->ut_line) + 1 and copying with an explicit terminator
removes the PATH_MAX dependency just as well and is a smaller diff. I am
happy to send that instead; I went with the allocation because it makes no
assumption about the utmp field width.

Toolchain stamp:
- hurd 1:0.9.git20260527-3+b1
- libc0.3 2.42-17
- gcc-15 15.3.0-1
- binutils 2.46.90.20260712-1

netkit-ntalk is maintained by the Debian QA Group and the netkit collection
has no active upstream, so there is nowhere to forward this fix =E2=80=94 h=
ence
"Forwarded: no" in the DEP-3 header below, and this report rather than an
upstream submission.

Assisted-by: hurd-collab agent (automated portability triage and fix)
Signed-off-by: Federico Bonino <[email protected]>

--- netkit-ntalk-hurd.patch ---
Description: Replace PATH_MAX buffer with dynamic allocation and add
MAXHOSTNAMELEN fallback for GNU/Hurd
Source-Version: 0.17-20
Author: Federico Bonino <[email protected]>
Forwarded: no
Last-Update: 2026-07-28

GNU/Hurd does not define PATH_MAX because it has no fixed path limit. The
besttty buffer in talkd/process.c was only used as a temporary scratch area
to hold a utmp tty line before copying it to the caller's output buffer; it
is now dynamically allocated with strdup, removing the fixed-size PATH_MAX
dependency.

The MAXHOSTNAMELEN buffer in talk/get_names.c is used for gethostname and
the legacy talk wire protocol uses fixed-size fields, so a bounded hostname
buffer remains appropriate. Since Hurd does not provide MAXHOSTNAMELEN,
provide a conditional fallback to HOST_NAME_MAX (or _POSIX_HOST_NAME_MAX)
from
<limits.h>, preserving the existing behaviour on BSD/Linux platforms.

--- a/talkd/process.c
+++ b/talkd/process.c
@@ -55,6 +55,7 @@ char rcsid[] =3D
 #include <syslog.h>
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
 /* #include <paths.h> <---- unused? */
 #include <utmp.h>
 #include "prot_talkd.h"
@@ -119,9 +120,12 @@ find_user(const char *name, char *tty)
  struct utmp *uptr;
  int found=3D0, ok=3D0, ret;
  time_t best_time =3D 0, this_time;
- char besttty[PATH_MAX];
+ char *besttty;

- *besttty =3D 0;
+ besttty =3D strdup("");
+ if (besttty =3D=3D NULL) {
+ return FAILED;
+ }
  setutent();
  while ((uptr =3D getutent())!=3DNULL) {
 #ifdef USER_PROCESS
@@ -135,6 +139,7 @@ find_user(const char *name, char *tty)
  if (*tty && !strcmp(tty, uptr->ut_line)) {
  /* asked for a tty, found it */
  endutent();
+ free(besttty);
  return SUCCESS;
  }
  ret =3D check_tty_perms(uptr->ut_line, &this_time);
@@ -145,11 +150,17 @@ find_user(const char *name, char *tty)
  found =3D ok =3D 1;
  if (this_time > best_time) {
  best_time =3D this_time;
- strcpy(besttty, uptr->ut_line);
+ free(besttty);
+ besttty =3D strdup(uptr->ut_line);
+ if (besttty =3D=3D NULL) {
+ endutent();
+ return FAILED;
+ }
  }
  }
  endutent();
  strcpy(tty, besttty);
+ free(besttty);
  return !found ? NOT_HERE : (!ok ? PERMISSION_DENIED : SUCCESS);
 }

--- a/talk/get_names.c
+++ b/talk/get_names.c
@@ -39,6 +39,14 @@ char gn_rcsid[] =3D

 #include <stdio.h>
 #include <sys/param.h>
+#include <limits.h>
+#ifndef MAXHOSTNAMELEN
+#ifdef HOST_NAME_MAX
+#define MAXHOSTNAMELEN HOST_NAME_MAX
+#else
+#define MAXHOSTNAMELEN _POSIX_HOST_NAME_MAX
+#endif
+#endif
 #include <sys/socket.h>
 #include <pwd.h>
 #include <unistd.h>

--00000000000007e9a90657c5df21
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Source: netkit-ntalk<br>Version: 0.17-20<br>Severity: impo=
rtant<br>Tags: patch, ftbfs<br>User: <a href=3D"mailto:[email protected]=
bian.org">[email protected]</a><br>Usertags: hurd-amd64<br>X-Deb=
bugs-Cc: <a href=3D"mailto:[email protected]">debian-hurd@lists.=
debian.org</a><br><br>netkit-ntalk fails to build from source on hurd-amd64=
 because two macros the source relies on=C2=A0are not defined by the Hurd l=
ibc headers:<br><br>Buildd log (hurd-amd64, 0.17-20): <a href=3D"https://bu=
ildd.debian.org/status/fetch.php?pkg=3Dnetkit-ntalk&amp;arch=3Dhurd-amd64&a=
mp;ver=3D0.17-20&amp;stamp=3D1783711377&amp;raw=3D1">https://buildd.debian.=
org/status/fetch.php?pkg=3Dnetkit-ntalk&amp;arch=3Dhurd-amd64&amp;ver=3D0.1=
7-20&amp;stamp=3D1783711377&amp;raw=3D1</a><br><br>=C2=A0 talk/get_names.c:=
55:23: error: &#39;MAXHOSTNAMELEN&#39; undeclared (first use in this functi=
on)<br>=C2=A0 =C2=A0 =C2=A055 | =C2=A0 =C2=A0 =C2=A0 =C2=A0 char hostname[M=
AXHOSTNAMELEN];<br><br>The build stops there. One file later, talkd/process=
.c:122 declares find_user()&#39;s scratch buffer as &quot;char besttty[PATH=
_MAX]&quot;, which does not compile on Hurd either.<br><br>Root cause: GNU/=
Hurd has no fixed path limit, so PATH_MAX is not defined.<br>MAXHOSTNAMELEN=
 is a BSD constant that is also absent on Hurd.<br><br>The patch below repl=
aces the PATH_MAX-sized temporary buffer in talkd/process.c with dynamic al=
location. It also supplies MAXHOSTNAMELEN from HOST_NAME_MAX, or from _POSI=
X_HOST_NAME_MAX when HOST_NAME_MAX is unavailable. No feature or test is di=
sabled.<br><br>I verified the patch on native GNU/Hurd amd64 running Debian=
 unstable. The unmodified 0.17-20 source reproduced the MAXHOSTNAMELEN buil=
d failure. The patch then applied with zero fuzz and zero offset, and dpkg-=
buildpackage completed successfully, producing talk and talkd. The package =
defines no autopkgtest or upstream test suite.<br><br>One thing to flag rat=
her than let you find it in your own build log: on GCC 15 the new strdup(up=
tr-&gt;ut_line) call raises<br><br>=C2=A0 warning: &#39;strdup&#39; argumen=
t 1 declared attribute &#39;nonstring&#39; [-Wstringop-overread]<br><br>bec=
ause ut_line is a fixed-size utmp field with no guaranteed NUL terminator.<=
br>The strcpy() it replaces read ut_line exactly the same way, so this is a=
 new diagnostic rather than a new unbounded read =E2=80=94 but it is new, a=
nd it appears on every architecture. If you would prefer the variant withou=
t it, sizing besttty<br>as sizeof(uptr-&gt;ut_line) + 1 and copying with an=
 explicit terminator removes the PATH_MAX dependency just as well and is a =
smaller diff. I am happy to send that instead; I went with the allocation b=
ecause it makes no assumption about the utmp field width.<div><br>Toolchain=
 stamp:<br>- hurd 1:0.9.git20260527-3+b1<br>- libc0.3 2.42-17<br>- gcc-15 1=
5.3.0-1<br>- binutils 2.46.90.20260712-1<br><br>netkit-ntalk is maintained =
by the Debian QA Group and the netkit collection has no active upstream, so=
 there is nowhere to forward this fix =E2=80=94 hence &quot;Forwarded: no&q=
uot; in the DEP-3 header below, and this report rather than an<br>upstream =
submission.<br><br>Assisted-by: hurd-collab agent (automated portability tr=
iage and fix)<br>Signed-off-by: Federico Bonino &lt;<a href=3D"mailto:buzon=
[email protected]">[email protected]</a>&gt;<br><br>--- netkit-ntalk-hur=
d.patch ---<br>Description: Replace PATH_MAX buffer with dynamic allocation=
 and add MAXHOSTNAMELEN fallback for GNU/Hurd<br>Source-Version: 0.17-20<br=
>Author: Federico Bonino &lt;<a href=3D"mailto:[email protected]">buzon=
[email protected]</a>&gt;<br>Forwarded: no<br>Last-Update: 2026-07-28<br><br=
>GNU/Hurd does not define PATH_MAX because it has no fixed path limit. The =
besttty buffer in talkd/process.c was only used as a temporary scratch area=
 to hold a utmp tty line before copying it to the caller&#39;s output buffe=
r; it is now dynamically allocated with strdup, removing the fixed-size PAT=
H_MAX dependency.<br><br>The MAXHOSTNAMELEN buffer in talk/get_names.c is u=
sed for gethostname and the legacy talk wire protocol uses fixed-size field=
s, so a bounded hostname buffer remains appropriate. Since Hurd does not pr=
ovide MAXHOSTNAMELEN, provide a conditional fallback to HOST_NAME_MAX (or _=
POSIX_HOST_NAME_MAX) from<br>&lt;limits.h&gt;, preserving the existing beha=
viour on BSD/Linux platforms.<br><br>--- a/talkd/process.c<br>+++ b/talkd/p=
rocess.c<br>@@ -55,6 +55,7 @@ char rcsid[] =3D<br>=C2=A0#include &lt;syslog=
.h&gt;<br>=C2=A0#include &lt;stdio.h&gt;<br>=C2=A0#include &lt;string.h&gt;=
<br>+#include &lt;stdlib.h&gt;<br>=C2=A0/* #include &lt;paths.h&gt; &lt;---=
- unused? */<br>=C2=A0#include &lt;utmp.h&gt;<br>=C2=A0#include &quot;prot_=
talkd.h&quot;<br>@@ -119,9 +120,12 @@ find_user(const char *name, char *tty=
)<br>=C2=A0	struct utmp *uptr;<br>=C2=A0	int found=3D0, ok=3D0, ret;<br>=C2=
=A0	time_t best_time =3D 0, this_time;<br>-	char besttty[PATH_MAX];<br>+	ch=
ar *besttty;<br><br>-	*besttty =3D 0;<br>+	besttty =3D strdup(&quot;&quot;)=
;<br>+	if (besttty =3D=3D NULL) {<br>+		return FAILED;<br>+	}<br>=C2=A0	set=
utent();<br>=C2=A0	while ((uptr =3D getutent())!=3DNULL) {<br>=C2=A0#ifdef =
USER_PROCESS<br>@@ -135,6 +139,7 @@ find_user(const char *name, char *tty)<=
br>=C2=A0		if (*tty &amp;&amp; !strcmp(tty, uptr-&gt;ut_line)) {<br>=C2=A0	=
		/* asked for a tty, found it */<br>=C2=A0			endutent();<br>+			free(bestt=
ty);<br>=C2=A0			return SUCCESS;<br>=C2=A0		}<br>=C2=A0		ret =3D check_tty_=
perms(uptr-&gt;ut_line, &amp;this_time);<br>@@ -145,11 +150,17 @@ find_user=
(const char *name, char *tty)<br>=C2=A0		found =3D ok =3D 1;<br>=C2=A0		if =
(this_time &gt; best_time) {<br>=C2=A0			best_time =3D this_time;<br>-			st=
rcpy(besttty, uptr-&gt;ut_line);<br>+			free(besttty);<br>+			besttty =3D s=
trdup(uptr-&gt;ut_line);<br>+			if (besttty =3D=3D NULL) {<br>+				endutent=
();<br>+				return FAILED;<br>+			}<br>=C2=A0		}<br>=C2=A0	}<br>=C2=A0	endu=
tent();<br>=C2=A0	strcpy(tty, besttty);<br>+	free(besttty);<br>=C2=A0	retur=
n !found ? NOT_HERE : (!ok ? PERMISSION_DENIED : SUCCESS);<br>=C2=A0}<br><b=
r>--- a/talk/get_names.c<br>+++ b/talk/get_names.c<br>@@ -39,6 +39,14 @@ ch=
ar gn_rcsid[] =3D<br><br>=C2=A0#include &lt;stdio.h&gt;<br>=C2=A0#include &=
lt;sys/param.h&gt;<br>+#include &lt;limits.h&gt;<br>+#ifndef MAXHOSTNAMELEN=
<br>+#ifdef HOST_NAME_MAX<br>+#define MAXHOSTNAMELEN HOST_NAME_MAX<br>+#els=
e<br>+#define MAXHOSTNAMELEN _POSIX_HOST_NAME_MAX<br>+#endif<br>+#endif<br>=
=C2=A0#include &lt;sys/socket.h&gt;<br>=C2=A0#include &lt;pwd.h&gt;<br>=C2=
=A0#include &lt;unistd.h&gt;<br><br></div></div>

--00000000000007e9a90657c5df21--