1*2dd10e69Sriastradh /* $NetBSD: strlcat.c,v 1.5 2024/11/01 21:11:37 riastradh Exp $ */ 237c9f0a6Schristos /* $OpenBSD: strlcat.c,v 1.10 2003/04/12 21:56:39 millert Exp $ */ 337c9f0a6Schristos 437c9f0a6Schristos /* 537c9f0a6Schristos * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> 637c9f0a6Schristos * 737c9f0a6Schristos * Permission to use, copy, modify, and distribute this software for any 837c9f0a6Schristos * purpose with or without fee is hereby granted, provided that the above 937c9f0a6Schristos * copyright notice and this permission notice appear in all copies. 1037c9f0a6Schristos * 1137c9f0a6Schristos * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL 1237c9f0a6Schristos * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 1337c9f0a6Schristos * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE 1437c9f0a6Schristos * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1537c9f0a6Schristos * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 1637c9f0a6Schristos * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 1737c9f0a6Schristos * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1837c9f0a6Schristos */ 1937c9f0a6Schristos 2037c9f0a6Schristos #if !defined(_KERNEL) && !defined(_STANDALONE) 2137c9f0a6Schristos #if HAVE_NBTOOL_CONFIG_H 2237c9f0a6Schristos #include "nbtool_config.h" 2337c9f0a6Schristos #endif 2437c9f0a6Schristos 2537c9f0a6Schristos #include <sys/cdefs.h> 2637c9f0a6Schristos #if defined(LIBC_SCCS) && !defined(lint) 27*2dd10e69Sriastradh __RCSID("$NetBSD: strlcat.c,v 1.5 2024/11/01 21:11:37 riastradh Exp $"); 2837c9f0a6Schristos #endif /* LIBC_SCCS and not lint */ 2937c9f0a6Schristos 3037c9f0a6Schristos #ifdef _LIBC 3137c9f0a6Schristos #include "namespace.h" 3237c9f0a6Schristos #endif 3337c9f0a6Schristos #include <sys/types.h> 3437c9f0a6Schristos #include <assert.h> 3537c9f0a6Schristos #include <string.h> 3637c9f0a6Schristos 3737c9f0a6Schristos #ifdef _LIBC 3837c9f0a6Schristos # ifdef __weak_alias 3937c9f0a6Schristos __weak_alias(strlcat, _strlcat) 4037c9f0a6Schristos # endif 4137c9f0a6Schristos #endif 4237c9f0a6Schristos 4337c9f0a6Schristos #else 4437c9f0a6Schristos #include <lib/libkern/libkern.h> 4537c9f0a6Schristos #endif /* !_KERNEL && !_STANDALONE */ 4637c9f0a6Schristos 4737c9f0a6Schristos #if !HAVE_STRLCAT 4837c9f0a6Schristos /* 4937c9f0a6Schristos * Appends src to string dst of size siz (unlike strncat, siz is the 5037c9f0a6Schristos * full size of dst, not space left). At most siz-1 characters 5137c9f0a6Schristos * will be copied. Always NUL terminates (unless siz <= strlen(dst)). 5237c9f0a6Schristos * Returns strlen(src) + MIN(siz, strlen(initial dst)). 5337c9f0a6Schristos * If retval >= siz, truncation occurred. 5437c9f0a6Schristos */ 5537c9f0a6Schristos size_t 56*2dd10e69Sriastradh strlcat(char *__restrict dst, const char *__restrict src, size_t siz) 5737c9f0a6Schristos { 58cd7877ebSmatt #if 1 5937c9f0a6Schristos char *d = dst; 6037c9f0a6Schristos const char *s = src; 6137c9f0a6Schristos size_t n = siz; 6237c9f0a6Schristos size_t dlen; 6337c9f0a6Schristos 6437c9f0a6Schristos _DIAGASSERT(dst != NULL); 6537c9f0a6Schristos _DIAGASSERT(src != NULL); 6637c9f0a6Schristos 6737c9f0a6Schristos /* Find the end of dst and adjust bytes left but don't go past end */ 6837c9f0a6Schristos while (n-- != 0 && *d != '\0') 6937c9f0a6Schristos d++; 7037c9f0a6Schristos dlen = d - dst; 7137c9f0a6Schristos n = siz - dlen; 7237c9f0a6Schristos 7337c9f0a6Schristos if (n == 0) 7437c9f0a6Schristos return(dlen + strlen(s)); 7537c9f0a6Schristos while (*s != '\0') { 7637c9f0a6Schristos if (n != 1) { 7737c9f0a6Schristos *d++ = *s; 7837c9f0a6Schristos n--; 7937c9f0a6Schristos } 8037c9f0a6Schristos s++; 8137c9f0a6Schristos } 8237c9f0a6Schristos *d = '\0'; 8337c9f0a6Schristos 8437c9f0a6Schristos return(dlen + (s - src)); /* count does not include NUL */ 85cd7877ebSmatt #else 86cd7877ebSmatt _DIAGASSERT(dst != NULL); 87cd7877ebSmatt _DIAGASSERT(src != NULL); 88cd7877ebSmatt 89cd7877ebSmatt /* 90cd7877ebSmatt * Find length of string in dst (maxing out at siz). 91cd7877ebSmatt */ 92cd7877ebSmatt size_t dlen = strnlen(dst, siz); 93cd7877ebSmatt 94cd7877ebSmatt /* 95cd7877ebSmatt * Copy src into any remaining space in dst (truncating if needed). 96cd7877ebSmatt * Note strlcpy(dst, src, 0) returns strlen(src). 97cd7877ebSmatt */ 98cd7877ebSmatt return dlen + strlcpy(dst + dlen, src, siz - dlen); 99cd7877ebSmatt #endif 10037c9f0a6Schristos } 10137c9f0a6Schristos #endif 102