1*b6cbf720SGianluca Guida /* $NetBSD: strlcat.c,v 1.3 2007/06/04 18:19:27 christos Exp $ */ 2*b6cbf720SGianluca Guida /* $OpenBSD: strlcat.c,v 1.10 2003/04/12 21:56:39 millert Exp $ */ 3*b6cbf720SGianluca Guida 4*b6cbf720SGianluca Guida /* 5*b6cbf720SGianluca Guida * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> 6*b6cbf720SGianluca Guida * 7*b6cbf720SGianluca Guida * Permission to use, copy, modify, and distribute this software for any 8*b6cbf720SGianluca Guida * purpose with or without fee is hereby granted, provided that the above 9*b6cbf720SGianluca Guida * copyright notice and this permission notice appear in all copies. 10*b6cbf720SGianluca Guida * 11*b6cbf720SGianluca Guida * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL 12*b6cbf720SGianluca Guida * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 13*b6cbf720SGianluca Guida * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE 14*b6cbf720SGianluca Guida * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15*b6cbf720SGianluca Guida * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 16*b6cbf720SGianluca Guida * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 17*b6cbf720SGianluca Guida * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18*b6cbf720SGianluca Guida */ 19*b6cbf720SGianluca Guida 20*b6cbf720SGianluca Guida #if !defined(_KERNEL) && !defined(_STANDALONE) 21*b6cbf720SGianluca Guida #if HAVE_NBTOOL_CONFIG_H 22*b6cbf720SGianluca Guida #include "nbtool_config.h" 23*b6cbf720SGianluca Guida #endif 24*b6cbf720SGianluca Guida 25*b6cbf720SGianluca Guida #include <sys/cdefs.h> 26*b6cbf720SGianluca Guida #if defined(LIBC_SCCS) && !defined(lint) 27*b6cbf720SGianluca Guida __RCSID("$NetBSD: strlcat.c,v 1.3 2007/06/04 18:19:27 christos Exp $"); 28*b6cbf720SGianluca Guida #endif /* LIBC_SCCS and not lint */ 29*b6cbf720SGianluca Guida 30*b6cbf720SGianluca Guida #ifdef _LIBC 31*b6cbf720SGianluca Guida #include "namespace.h" 32*b6cbf720SGianluca Guida #endif 33*b6cbf720SGianluca Guida #include <sys/types.h> 34*b6cbf720SGianluca Guida #include <assert.h> 35*b6cbf720SGianluca Guida #include <string.h> 36*b6cbf720SGianluca Guida 37*b6cbf720SGianluca Guida #ifdef _LIBC 38*b6cbf720SGianluca Guida # ifdef __weak_alias 39*b6cbf720SGianluca Guida __weak_alias(strlcat, _strlcat) 40*b6cbf720SGianluca Guida # endif 41*b6cbf720SGianluca Guida #endif 42*b6cbf720SGianluca Guida 43*b6cbf720SGianluca Guida #else 44*b6cbf720SGianluca Guida #include <lib/libkern/libkern.h> 45*b6cbf720SGianluca Guida #endif /* !_KERNEL && !_STANDALONE */ 46*b6cbf720SGianluca Guida 47*b6cbf720SGianluca Guida #if !HAVE_STRLCAT 48*b6cbf720SGianluca Guida /* 49*b6cbf720SGianluca Guida * Appends src to string dst of size siz (unlike strncat, siz is the 50*b6cbf720SGianluca Guida * full size of dst, not space left). At most siz-1 characters 51*b6cbf720SGianluca Guida * will be copied. Always NUL terminates (unless siz <= strlen(dst)). 52*b6cbf720SGianluca Guida * Returns strlen(src) + MIN(siz, strlen(initial dst)). 53*b6cbf720SGianluca Guida * If retval >= siz, truncation occurred. 54*b6cbf720SGianluca Guida */ 55*b6cbf720SGianluca Guida size_t 56*b6cbf720SGianluca Guida strlcat(char *dst, const char *src, size_t siz) 57*b6cbf720SGianluca Guida { 58*b6cbf720SGianluca Guida char *d = dst; 59*b6cbf720SGianluca Guida const char *s = src; 60*b6cbf720SGianluca Guida size_t n = siz; 61*b6cbf720SGianluca Guida size_t dlen; 62*b6cbf720SGianluca Guida 63*b6cbf720SGianluca Guida _DIAGASSERT(dst != NULL); 64*b6cbf720SGianluca Guida _DIAGASSERT(src != NULL); 65*b6cbf720SGianluca Guida 66*b6cbf720SGianluca Guida /* Find the end of dst and adjust bytes left but don't go past end */ 67*b6cbf720SGianluca Guida while (n-- != 0 && *d != '\0') 68*b6cbf720SGianluca Guida d++; 69*b6cbf720SGianluca Guida dlen = d - dst; 70*b6cbf720SGianluca Guida n = siz - dlen; 71*b6cbf720SGianluca Guida 72*b6cbf720SGianluca Guida if (n == 0) 73*b6cbf720SGianluca Guida return(dlen + strlen(s)); 74*b6cbf720SGianluca Guida while (*s != '\0') { 75*b6cbf720SGianluca Guida if (n != 1) { 76*b6cbf720SGianluca Guida *d++ = *s; 77*b6cbf720SGianluca Guida n--; 78*b6cbf720SGianluca Guida } 79*b6cbf720SGianluca Guida s++; 80*b6cbf720SGianluca Guida } 81*b6cbf720SGianluca Guida *d = '\0'; 82*b6cbf720SGianluca Guida 83*b6cbf720SGianluca Guida return(dlen + (s - src)); /* count does not include NUL */ 84*b6cbf720SGianluca Guida } 85*b6cbf720SGianluca Guida #endif 86