diff --git a/lib/Makefile.am b/lib/Makefile.am index d709345986..34858a769f 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -115,6 +115,8 @@ libshadow_la_SOURCES = \ lockpw.c \ loginprompt.c \ mail.c \ + memory/memcpy/strncpytail.c \ + memory/memcpy/strncpytail.h \ motd.c \ myname.c \ nss.c \ diff --git a/lib/memory/memcpy/strncpytail.c b/lib/memory/memcpy/strncpytail.c new file mode 100644 index 0000000000..f4b2847f76 --- /dev/null +++ b/lib/memory/memcpy/strncpytail.c @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: 2025-2026, Alejandro Colomar +// SPDX-License-Identifier: BSD-3-Clause + + +#include "config.h" + +#include "memory/memcpy/strncpytail.h" + +#include + + +extern inline char *strncpytail(char *restrict dst, const char *restrict src, + size_t dsize); diff --git a/lib/memory/memcpy/strncpytail.h b/lib/memory/memcpy/strncpytail.h new file mode 100644 index 0000000000..02b5732384 --- /dev/null +++ b/lib/memory/memcpy/strncpytail.h @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: 2025-2026, Alejandro Colomar +// SPDX-License-Identifier: BSD-3-Clause + + +#ifndef SHADOW_INCLUDE_LIB_MEMORY_MEMCPY_STRNCPYTAIL_H_ +#define SHADOW_INCLUDE_LIB_MEMORY_MEMCPY_STRNCPYTAIL_H_ + + +#include "config.h" + +#include +#include +#include +#include + +#include "attr.h" +#include "sizeof.h" +#include "string/strchr/strnul.h" + + +// strncpytail_a - nonstring copy tail-of-string array +#define strncpytail_a(dst, src) strncpytail(dst, src, countof(dst)) + + +ATTR_STRING(2) +inline char *strncpytail(char *restrict dst, const char *restrict src, + size_t dsize); + + +// strncpytail - nonstring copy tail-of-string +inline char * +strncpytail(char *restrict dst, const char *restrict src, size_t dsize) +{ + return strncpy(dst, strnul(src) - MIN(strlen(src), dsize), dsize); +} + + +#endif // include guard diff --git a/lib/string/README b/lib/string/README index 70274d71de..5a6042341e 100644 --- a/lib/string/README +++ b/lib/string/README @@ -179,7 +179,7 @@ strcpy/ - String copying strncpytail() Like strncpy(), but when truncating, the tail of the string is kept instead of the beginning. This is useful for ut_id. - STRNCPYTAIL() + strncpytail_a() Like strncpytail, but takes an array. strncat_a() // To be removed diff --git a/lib/utmp.c b/lib/utmp.c index 62002768e6..8617be08f7 100644 --- a/lib/utmp.c +++ b/lib/utmp.c @@ -30,6 +30,7 @@ #include "alloc/malloc.h" #include "attr.h" #include "io/syslog.h" +#include "memory/memcpy/strncpytail.h" #include "sizeof.h" #include "string/strchr/strnul.h" #include "string/strcmp/streq.h" @@ -285,12 +286,10 @@ prepare_utmp(const char *name, const char *line, const char *host, utent->ut_type = USER_PROCESS; utent->ut_pid = main_pid; strncpy_a(utent->ut_line, line); - if ( (NULL != ut) - && ('\0' != ut->ut_id[0])) { + if (NULL != ut && !strneq_a(ut->ut_id, "")) strncpy_a(utent->ut_id, ut->ut_id); - } else { - strncpy_a(utent->ut_id, strnul(line) - MIN(strlen(line), countof(utent->ut_id))); - } + else + strncpytail_a(utent->ut_id, line); #if defined(HAVE_STRUCT_UTMPX_UT_NAME) strncpy_a(utent->ut_name, name); #endif