Index: kernel/ksyms.c =================================================================== --- kernel/ksyms.c (revision 10041) +++ kernel/ksyms.c (working copy) @@ -578,6 +578,8 @@ EXPORT_SYMBOL(strnicmp); EXPORT_SYMBOL(strspn); EXPORT_SYMBOL(strsep); +EXPORT_SYMBOL(strlcat); +EXPORT_SYMBOL(strlcpy); /* software interrupts */ EXPORT_SYMBOL(tasklet_init); Index: include/linux/string.h =================================================================== --- include/linux/string.h (revision 10041) +++ include/linux/string.h (working copy) @@ -25,12 +25,18 @@ #ifndef __HAVE_ARCH_STRCPY extern char * strcpy(char *,const char *); #endif +#ifndef __HAVE_ARCH_STRLCPY +extern size_t strlcpy(char *dest, const char *src, size_t size); +#endif #ifndef __HAVE_ARCH_STRNCPY extern char * strncpy(char *,const char *, __kernel_size_t); #endif #ifndef __HAVE_ARCH_STRCAT extern char * strcat(char *, const char *); #endif +#ifndef __HAVE_ARCH_STRLCAT +extern size_t strlcat(char *dest, const char *src, size_t size); +#endif #ifndef __HAVE_ARCH_STRNCAT extern char * strncat(char *, const char *, __kernel_size_t); #endif Index: lib/string.c =================================================================== --- lib/string.c (revision 10041) +++ lib/string.c (working copy) @@ -17,8 +17,40 @@ * * Sat Feb 09 2002, Jason Thomas , * Matthew Hawkins * - Kissed strtok() goodbye + * + * * Sun May 25 2003, Ben Collins + * - Added strlcpy and strlcat, which will replace strncpy and strncat + * since they are safer and guarantee a NUL-terminated dest. */ - + +/* Following applies to strlcpy and strlcat */ +/* + * Copyright (c) 2001 Richard Kettlewell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + #include #include #include @@ -72,6 +104,35 @@ } #endif +#ifndef __HAVE_ARCH_STRLCPY +/** + * strlcpy - Copy a length-limited, %NUL-terminated string + * @dest: Where to copy the string to + * @src: Where to copy the string from + * @size: The size of the @dest buffer + * + * Note that unlike strncpy, the result is always guaranteed to be + * %NUL-terminated but is not %NUL-padded. This is much safer than + * strncpy. The return value is basically strlen(src), which means you can + * use it to check if the result should have been longer than @size, + * meaning it was truncated. + */ +size_t strlcpy(char *dest, const char *src, size_t size) +{ + size_t l = strlen(src); + + if (l >= size) { + if (size) { + memcpy(dest, src, size - 1); + dest[size - 1] = 0; + } + } else if (l) + memcpy(dest, src, l + 1); + + return l; +} +#endif + #ifndef __HAVE_ARCH_STRNCPY /** * strncpy - Copy a length-limited, %NUL-terminated string @@ -113,6 +174,53 @@ } #endif +#ifndef __HAVE_ARCH_STRLCAT +/** + * strlcat - Append a length-limited, %NUL-terminated string to another + * @dest: The string to be appended to + * @src: The string to append to it + * @size: The size of the @dest buffer + * + * Note that even though strncat %NUL-terminates, this function is more + * useful since it is easier to check for truncation. + * + * Unlink strncat, @size is the total size of @dest, not just the amount + * left. The return value is strlen(src) + strlen(initial dest)). + * + * If the return value is greater than @size, truncation occured. + */ +size_t strlcat(char *dest, const char *src, size_t size) +{ + size_t sl = strlen(src); + size_t dl, tl; + + /* strlcpy wont give us NULL termination if size is 0, so we can't + * check strlen(dest) if someone does this scenario: + * + * strlcpy(dest, "My ", 0); + * strlcat(dest, "string", 0); + * + * Stupid, I know, but just a check. + */ + if (!size) + return sl; + + dl = strlen(dest); + tl = sl + dl; + + if (tl >= size) { + /* Truncation occurs, but check for room */ + if (size > dl) { + memcpy(dest + dl, src, size - dl - 1); + dest[size - 1] = 0; + } + } else + memcpy(dest + dl, src, sl + 1); + + return tl; +} +#endif + #ifndef __HAVE_ARCH_STRNCAT /** * strncat - Append a length-limited, %NUL-terminated string to another