1301169Slidl/* $NetBSD: strlcat.c,v 1.2 2015/01/22 03:48:07 christos Exp $ */ 2301169Slidl/* $OpenBSD: strlcat.c,v 1.10 2003/04/12 21:56:39 millert Exp $ */ 3301169Slidl 4301169Slidl/* 5301169Slidl * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> 6301169Slidl * 7301169Slidl * Permission to use, copy, modify, and distribute this software for any 8301169Slidl * purpose with or without fee is hereby granted, provided that the above 9301169Slidl * copyright notice and this permission notice appear in all copies. 10301169Slidl * 11301169Slidl * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL 12301169Slidl * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 13301169Slidl * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE 14301169Slidl * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15301169Slidl * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 16301169Slidl * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 17301169Slidl * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18301169Slidl */ 19301169Slidl 20301169Slidl#if !defined(_KERNEL) && !defined(_STANDALONE) 21301169Slidl#if HAVE_CONFIG_H 22301169Slidl#include "config.h" 23301169Slidl#endif 24301169Slidl 25301169Slidl#include <sys/cdefs.h> 26301169Slidl#if defined(LIBC_SCCS) && !defined(lint) 27301169Slidl__RCSID("$NetBSD: strlcat.c,v 1.2 2015/01/22 03:48:07 christos Exp $"); 28301169Slidl#endif /* LIBC_SCCS and not lint */ 29301169Slidl 30301169Slidl#ifdef _LIBC 31301169Slidl#include "namespace.h" 32301169Slidl#endif 33301169Slidl#include <sys/types.h> 34301169Slidl#include <assert.h> 35301169Slidl#include <string.h> 36301169Slidl 37301169Slidl#ifdef _LIBC 38301169Slidl# ifdef __weak_alias 39301169Slidl__weak_alias(strlcat, _strlcat) 40301169Slidl# endif 41301169Slidl#endif 42301169Slidl 43301169Slidl#else 44301169Slidl#include <lib/libkern/libkern.h> 45301169Slidl#endif /* !_KERNEL && !_STANDALONE */ 46301169Slidl 47301169Slidl#if !HAVE_STRLCAT 48301169Slidl/* 49301169Slidl * Appends src to string dst of size siz (unlike strncat, siz is the 50301169Slidl * full size of dst, not space left). At most siz-1 characters 51301169Slidl * will be copied. Always NUL terminates (unless siz <= strlen(dst)). 52301169Slidl * Returns strlen(src) + MIN(siz, strlen(initial dst)). 53301169Slidl * If retval >= siz, truncation occurred. 54301169Slidl */ 55301169Slidlsize_t 56301169Slidlstrlcat(char *dst, const char *src, size_t siz) 57301169Slidl{ 58301169Slidl#if 1 59301169Slidl char *d = dst; 60301169Slidl const char *s = src; 61301169Slidl size_t n = siz; 62301169Slidl size_t dlen; 63301169Slidl 64301169Slidl /* Find the end of dst and adjust bytes left but don't go past end */ 65301169Slidl while (n-- != 0 && *d != '\0') 66301169Slidl d++; 67301169Slidl dlen = d - dst; 68301169Slidl n = siz - dlen; 69301169Slidl 70301169Slidl if (n == 0) 71301169Slidl return(dlen + strlen(s)); 72301169Slidl while (*s != '\0') { 73301169Slidl if (n != 1) { 74301169Slidl *d++ = *s; 75301169Slidl n--; 76301169Slidl } 77301169Slidl s++; 78301169Slidl } 79301169Slidl *d = '\0'; 80301169Slidl 81301169Slidl return(dlen + (s - src)); /* count does not include NUL */ 82301169Slidl#else 83301169Slidl 84301169Slidl /* 85301169Slidl * Find length of string in dst (maxing out at siz). 86301169Slidl */ 87301169Slidl size_t dlen = strnlen(dst, siz); 88301169Slidl 89301169Slidl /* 90301169Slidl * Copy src into any remaining space in dst (truncating if needed). 91301169Slidl * Note strlcpy(dst, src, 0) returns strlen(src). 92301169Slidl */ 93301169Slidl return dlen + strlcpy(dst + dlen, src, siz - dlen); 94301169Slidl#endif 95301169Slidl} 96301169Slidl#endif 97