X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d7e50217d7adf6e52786a38bcaa4cd698cb9a79e..743345f9a4b36f7e2f9ba37691e70c50baecb56e:/osfmk/device/subrs.c diff --git a/osfmk/device/subrs.c b/osfmk/device/subrs.c index ccbb9990e..e36267988 100644 --- a/osfmk/device/subrs.c +++ b/osfmk/device/subrs.c @@ -1,16 +1,19 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER @@ -20,7 +23,7 @@ * Please see the License for the specific language governing rights and * limitations under the License. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * @OSF_COPYRIGHT@ @@ -92,12 +95,48 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ + +/* + * Copyright (c) 1998 Todd C. Miller + * 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. + */ + +/* + * NOTICE: This file was modified by McAfee Research in 2004 to introduce + * support for mandatory and extensible security protections. This notice + * is included in support of clause 2.2 (b) of the Apple Public License, + * Version 2.0. + */ /* * Random device subroutines and stubs. */ #include #include +#include +#include /* String routines, from CMU */ #ifdef strcpy @@ -118,14 +157,16 @@ * It returns < 0 if the first differing character is smaller * in s1 than in s2 or if s1 is shorter than s2 and the * contents are identical upto the length of s1. + * Deprecation Warning: + * strcmp() is being deprecated. Please use strncmp() instead. */ int strcmp( - register const char *s1, - register const char *s2) + const char *s1, + const char *s2) { - register unsigned int a, b; + unsigned int a, b; do { a = *s1++; @@ -146,13 +187,15 @@ strcmp( * comparison runs for at most "n" characters. */ +// ARM implementation in ../arm/strncmp.s +// ARM64 implementation in ../arm64/strncmp.s int strncmp( - register const char *s1, - register const char *s2, + const char *s1, + const char *s2, size_t n) { - register unsigned int a, b; + unsigned int a, b; while (n != 0) { a = *s1++; @@ -169,19 +212,63 @@ strncmp( return 0; } + +// +// Lame implementation just for use by strcasecmp/strncasecmp +// +static int +tolower(unsigned char ch) +{ + if (ch >= 'A' && ch <= 'Z') + ch = 'a' + (ch - 'A'); + + return ch; +} + +int +strcasecmp(const char *s1, const char *s2) +{ + const unsigned char *us1 = (const u_char *)s1, + *us2 = (const u_char *)s2; + + while (tolower(*us1) == tolower(*us2++)) + if (*us1++ == '\0') + return (0); + return (tolower(*us1) - tolower(*--us2)); +} + +int +strncasecmp(const char *s1, const char *s2, size_t n) +{ + if (n != 0) { + const unsigned char *us1 = (const u_char *)s1, + *us2 = (const u_char *)s2; + + do { + if (tolower(*us1) != tolower(*us2++)) + return (tolower(*us1) - tolower(*--us2)); + if (*us1++ == '\0') + break; + } while (--n != 0); + } + return (0); +} + + /* * Abstract: * strcpy copies the contents of the string "from" including * the null terminator to the string "to". A pointer to "to" * is returned. + * Deprecation Warning: + * strcpy() is being deprecated. Please use strlcpy() instead. */ - char * strcpy( - register char *to, - register const char *from) + char *to, + const char *from) { - register char *ret = to; + char *ret = to; while ((*to++ = *from++) != '\0') continue; @@ -189,7 +276,6 @@ strcpy( return ret; } - /* * Abstract: * strncpy copies "count" characters from the "from" string to @@ -199,6 +285,7 @@ strcpy( * to the "to" string. */ +// ARM and ARM64 implementation in ../arm/strncpy.c char * strncpy( char *s1, @@ -227,8 +314,7 @@ strncpy( */ int -atoi( - u_char *cp) +atoi(const char *cp) { int number; @@ -255,8 +341,8 @@ atoi_term( char *p, /* IN */ char **t) /* OUT */ { - register int n; - register int f; + int n; + int f; n = 0; f = 0; @@ -282,6 +368,29 @@ atoi_term( return(f? -n: n); } +/* + * Does the same thing as strlen, except only looks up + * to max chars inside the buffer. + * Taken from archive/kern-stuff/sbf_machine.c in + * seatbelt. + * inputs: + * s string whose length is to be measured + * max maximum length of string to search for null + * outputs: + * length of s or max; whichever is smaller + */ + +// ARM implementation in ../arm/strnlen.s +// ARM64 implementation in ../arm64/strnlen.s +size_t +strnlen(const char *s, size_t max) { + const char *es = s + max, *p = s; + while(*p && p != es) + p++; + + return p - s; +} + /* * convert an integer to an ASCII string. * inputs: @@ -298,8 +407,8 @@ itoa( char *str) { char digits[11]; - register char *dp; - register char *cp = str; + char *dp; + char *cp = str; if (num == 0) { *cp++ = '0'; @@ -319,17 +428,166 @@ itoa( return str; } +/* + * Deprecation Warning: + * strcat() is being deprecated. Please use strlcat() instead. + */ char * strcat( - register char *dest, - register const char *src) + char *dest, + const char *src) { char *old = dest; while (*dest) ++dest; - while (*dest++ = *src++) + while ((*dest++ = *src++)) ; return (old); } +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +size_t +strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ + +// ARM and ARM64 implementation in ../arm/strlcpy.c +size_t +strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +/* + * STRDUP + * + * Description: The STRDUP function allocates sufficient memory for a copy + * of the string "string", does the copy, and returns a pointer + * it. The pointer may subsequently be used as an argument to + * the macro FREE(). + * + * Parameters: string String to be duplicated + * type type of memory to be allocated (normally + * M_TEMP) + * + * Returns: char * A pointer to the newly allocated string with + * duplicated contents in it. + * + * NULL If MALLOC() fails. + * + * Note: This function can *not* be called from interrupt context as + * it calls MALLOC with M_WAITOK. In fact, you really + * shouldn't be doing string manipulation in interrupt context + * ever. + * + * This function name violates the kernel style(9) guide + * by being all caps. This was done on purpose to emphasize + * one should use FREE() with the allocated buffer. + * + */ +char * +STRDUP(const char *string, int type) +{ + size_t len; + char *copy; + + len = strlen(string) + 1; + MALLOC(copy, char *, len, type, M_WAITOK); + if (copy == NULL) + return (NULL); + bcopy(string, copy, len); + return (copy); +} + +/* + * Return TRUE(1) if string 2 is a prefix of string 1. + */ +int +strprefix(const char *s1, const char *s2) +{ + int c; + + while ((c = *s2++) != '\0') { + if (c != *s1++) + return (0); + } + return (1); +} + +char * +strnstr(char *s, const char *find, size_t slen) +{ + char c, sc; + size_t len; + + if ((c = *find++) != '\0') { + len = strlen(find); + do { + do { + if ((sc = *s++) == '\0' || slen-- < 1) + return (NULL); + } while (sc != c); + if (len > slen) + return (NULL); + } while (strncmp(s, find, len) != 0); + s--; + } + return (s); +} +