1275970Scy/*
2275970Scy * Why use strlcpy()/strlcat() instead of standard strncpy()/strncat()?
3275970Scy * To reduce likelihood of bugs and avoid wasteful zero fills.  See:
4275970Scy * http://www.gratisoft.us/todd/papers/strlcpy.html
5275970Scy */
6275970Scy
7275970Scy/*	$OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $	*/
8275970Scy
9275970Scy/*
10275970Scy * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
11275970Scy *
12275970Scy * Permission to use, copy, modify, and distribute this software for any
13275970Scy * purpose with or without fee is hereby granted, provided that the above
14275970Scy * copyright notice and this permission notice appear in all copies.
15275970Scy *
16275970Scy * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
17275970Scy * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
18275970Scy * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
19275970Scy * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20275970Scy * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
21275970Scy * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
22275970Scy * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23275970Scy */
24275970Scy
25275970Scy#include <config.h>		/* + marks local changes */
26275970Scy#ifdef HAVE_SYS_TYPES_H		/* + */
27275970Scy#include <sys/types.h>
28275970Scy#endif				/* + */
29275970Scy#include <string.h>
30275970Scy
31275970Scy#include "ntp_stdlib.h"		/* + strlcpy, strlcat prototypes */
32275970Scy
33275970Scy#ifndef HAVE_STRLCPY		/* + */
34275970Scy/*
35275970Scy * Copy src to string dst of size siz.  At most siz-1 characters
36275970Scy * will be copied.  Always NUL terminates (unless siz == 0).
37275970Scy * Returns strlen(src); if retval >= siz, truncation occurred.
38275970Scy */
39275970Scysize_t
40275970Scystrlcpy(char *dst, const char *src, size_t siz)
41275970Scy{
42275970Scy	char *d = dst;
43275970Scy	const char *s = src;
44275970Scy	size_t n = siz;
45275970Scy
46275970Scy	/* Copy as many bytes as will fit */
47275970Scy	if (n != 0) {
48275970Scy		while (--n != 0) {
49275970Scy			if ((*d++ = *s++) == '\0')
50275970Scy				break;
51275970Scy		}
52275970Scy	}
53275970Scy
54275970Scy	/* Not enough room in dst, add NUL and traverse rest of src */
55275970Scy	if (n == 0) {
56275970Scy		if (siz != 0)
57275970Scy			*d = '\0';		/* NUL-terminate dst */
58275970Scy		while (*s++)
59275970Scy			;
60275970Scy	}
61275970Scy
62275970Scy	return(s - src - 1);	/* count does not include NUL */
63275970Scy}
64275970Scy#endif				/* + */
65275970Scy
66275970Scy
67275970Scy/*	$OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $	*/
68275970Scy
69275970Scy/*
70275970Scy * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
71275970Scy *
72275970Scy * Permission to use, copy, modify, and distribute this software for any
73275970Scy * purpose with or without fee is hereby granted, provided that the above
74275970Scy * copyright notice and this permission notice appear in all copies.
75275970Scy *
76275970Scy * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
77275970Scy * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
78275970Scy * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
79275970Scy * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
80275970Scy * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
81275970Scy * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
82275970Scy * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
83275970Scy */
84275970Scy
85275970Scy/* #include <sys/types.h> */	/* + */
86275970Scy/* #include <string.h> */	/* + */
87275970Scy
88275970Scy#ifndef HAVE_STRLCAT		/* + */
89275970Scy/*
90275970Scy * Appends src to string dst of size siz (unlike strncat, siz is the
91275970Scy * full size of dst, not space left).  At most siz-1 characters
92275970Scy * will be copied.  Always NUL terminates (unless siz <= strlen(dst)).
93275970Scy * Returns strlen(src) + MIN(siz, strlen(initial dst)).
94275970Scy * If retval >= siz, truncation occurred.
95275970Scy */
96275970Scysize_t
97275970Scystrlcat(char *dst, const char *src, size_t siz)
98275970Scy{
99275970Scy	char *d = dst;
100275970Scy	const char *s = src;
101275970Scy	size_t n = siz;
102275970Scy	size_t dlen;
103275970Scy
104275970Scy	/* Find the end of dst and adjust bytes left but don't go past end */
105275970Scy	while (n-- != 0 && *d != '\0')
106275970Scy		d++;
107275970Scy	dlen = d - dst;
108275970Scy	n = siz - dlen;
109275970Scy
110275970Scy	if (n == 0)
111275970Scy		return(dlen + strlen(s));
112275970Scy	while (*s != '\0') {
113275970Scy		if (n != 1) {
114275970Scy			*d++ = *s;
115275970Scy			n--;
116275970Scy		}
117275970Scy		s++;
118275970Scy	}
119275970Scy	*d = '\0';
120275970Scy
121275970Scy	return(dlen + (s - src));	/* count does not include NUL */
122275970Scy}
123275970Scy#endif				/* + */
124