1/* 2 * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* 29 * @OSF_COPYRIGHT@ 30 */ 31/* 32 *(C)UNIX System Laboratories, Inc. all or some portions of this file are 33 *derived from material licensed to the University of California by 34 *American Telephone and Telegraph Co. or UNIX System Laboratories, 35 *Inc. and are reproduced herein with the permission of UNIX System 36 *Laboratories, Inc. 37 */ 38 39/* 40 * Mach Operating System 41 * Copyright (c) 1993,1991,1990,1989,1988 Carnegie Mellon University 42 * All Rights Reserved. 43 * 44 * Permission to use, copy, modify and distribute this software and its 45 * documentation is hereby granted, provided that both the copyright 46 * notice and this permission notice appear in all copies of the 47 * software, derivative works or modified versions, and any portions 48 * thereof, and that both notices appear in supporting documentation. 49 * 50 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 51 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 52 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 53 * 54 * Carnegie Mellon requests users of this software to return to 55 * 56 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 57 * School of Computer Science 58 * Carnegie Mellon University 59 * Pittsburgh PA 15213-3890 60 * 61 * any improvements or extensions that they make and grant Carnegie Mellon 62 * the rights to redistribute these changes. 63 */ 64/* 65 */ 66/* 67 * Copyright (c) 1988 Regents of the University of California. 68 * All rights reserved. 69 * 70 * Redistribution and use in source and binary forms, with or without 71 * modification, are permitted provided that the following conditions 72 * are met: 73 * 1. Redistributions of source code must retain the above copyright 74 * notice, this list of conditions and the following disclaimer. 75 * 2. Redistributions in binary form must reproduce the above copyright 76 * notice, this list of conditions and the following disclaimer in the 77 * documentation and/or other materials provided with the distribution. 78 * 3. All advertising materials mentioning features or use of this software 79 * must display the following acknowledgement: 80 * This product includes software developed by the University of 81 * California, Berkeley and its contributors. 82 * 4. Neither the name of the University nor the names of its contributors 83 * may be used to endorse or promote products derived from this software 84 * without specific prior written permission. 85 * 86 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 87 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 88 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 89 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 90 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 91 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 92 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 93 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 94 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 95 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 96 * SUCH DAMAGE. 97 */ 98 99/* 100 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> 101 * All rights reserved. 102 * 103 * Redistribution and use in source and binary forms, with or without 104 * modification, are permitted provided that the following conditions 105 * are met: 106 * 1. Redistributions of source code must retain the above copyright 107 * notice, this list of conditions and the following disclaimer. 108 * 2. Redistributions in binary form must reproduce the above copyright 109 * notice, this list of conditions and the following disclaimer in the 110 * documentation and/or other materials provided with the distribution. 111 * 3. The name of the author may not be used to endorse or promote products 112 * derived from this software without specific prior written permission. 113 * 114 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 115 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 116 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 117 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 118 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 119 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 120 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 121 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 122 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 123 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 124 */ 125 126/* 127 * NOTICE: This file was modified by McAfee Research in 2004 to introduce 128 * support for mandatory and extensible security protections. This notice 129 * is included in support of clause 2.2 (b) of the Apple Public License, 130 * Version 2.0. 131 */ 132/* 133 * Random device subroutines and stubs. 134 */ 135 136#include <vm/vm_kern.h> 137#include <kern/misc_protos.h> 138#include <libsa/stdlib.h> 139#include <sys/malloc.h> 140 141/* String routines, from CMU */ 142#ifdef strcpy 143#undef strcmp 144#undef strncmp 145#undef strcpy 146#undef strncpy 147#undef strlen 148#endif 149 150/* 151 * Abstract: 152 * strcmp (s1, s2) compares the strings "s1" and "s2". 153 * It returns 0 if the strings are identical. It returns 154 * > 0 if the first character that differs in the two strings 155 * is larger in s1 than in s2 or if s1 is longer than s2 and 156 * the contents are identical up to the length of s2. 157 * It returns < 0 if the first differing character is smaller 158 * in s1 than in s2 or if s1 is shorter than s2 and the 159 * contents are identical upto the length of s1. 160 * Deprecation Warning: 161 * strcmp() is being deprecated. Please use strncmp() instead. 162 */ 163 164int 165strcmp( 166 const char *s1, 167 const char *s2) 168{ 169 unsigned int a, b; 170 171 do { 172 a = *s1++; 173 b = *s2++; 174 if (a != b) 175 return a-b; /* includes case when 176 'a' is zero and 'b' is not zero 177 or vice versa */ 178 } while (a != '\0'); 179 180 return 0; /* both are zero */ 181} 182 183/* 184 * Abstract: 185 * strncmp (s1, s2, n) compares the strings "s1" and "s2" 186 * in exactly the same way as strcmp does. Except the 187 * comparison runs for at most "n" characters. 188 */ 189 190// ARM implementation in ../arm/strncmp.s 191// ARM64 implementation in ../arm64/strncmp.s 192int 193strncmp( 194 const char *s1, 195 const char *s2, 196 size_t n) 197{ 198 unsigned int a, b; 199 200 while (n != 0) { 201 a = *s1++; 202 b = *s2++; 203 if (a != b) 204 return a-b; /* includes case when 205 'a' is zero and 'b' is not zero 206 or vice versa */ 207 if (a == '\0') 208 return 0; /* both are zero */ 209 n--; 210 } 211 212 return 0; 213} 214 215 216// 217// Lame implementation just for use by strcasecmp/strncasecmp 218// 219static int 220tolower(unsigned char ch) 221{ 222 if (ch >= 'A' && ch <= 'Z') 223 ch = 'a' + (ch - 'A'); 224 225 return ch; 226} 227 228int 229strcasecmp(const char *s1, const char *s2) 230{ 231 const unsigned char *us1 = (const u_char *)s1, 232 *us2 = (const u_char *)s2; 233 234 while (tolower(*us1) == tolower(*us2++)) 235 if (*us1++ == '\0') 236 return (0); 237 return (tolower(*us1) - tolower(*--us2)); 238} 239 240int 241strncasecmp(const char *s1, const char *s2, size_t n) 242{ 243 if (n != 0) { 244 const unsigned char *us1 = (const u_char *)s1, 245 *us2 = (const u_char *)s2; 246 247 do { 248 if (tolower(*us1) != tolower(*us2++)) 249 return (tolower(*us1) - tolower(*--us2)); 250 if (*us1++ == '\0') 251 break; 252 } while (--n != 0); 253 } 254 return (0); 255} 256 257 258/* 259 * Abstract: 260 * strcpy copies the contents of the string "from" including 261 * the null terminator to the string "to". A pointer to "to" 262 * is returned. 263 * Deprecation Warning: 264 * strcpy() is being deprecated. Please use strlcpy() instead. 265 */ 266char * 267strcpy( 268 char *to, 269 const char *from) 270{ 271 char *ret = to; 272 273 while ((*to++ = *from++) != '\0') 274 continue; 275 276 return ret; 277} 278 279/* 280 * Abstract: 281 * strncpy copies "count" characters from the "from" string to 282 * the "to" string. If "from" contains less than "count" characters 283 * "to" will be padded with null characters until exactly "count" 284 * characters have been written. The return value is a pointer 285 * to the "to" string. 286 */ 287 288// ARM and ARM64 implementation in ../arm/strncpy.c 289char * 290strncpy( 291 char *s1, 292 const char *s2, 293 size_t n) 294{ 295 char *os1 = s1; 296 unsigned long i; 297 298 for (i = 0; i < n;) 299 if ((*s1++ = *s2++) == '\0') 300 for (i++; i < n; i++) 301 *s1++ = '\0'; 302 else 303 i++; 304 return (os1); 305} 306 307/* 308 * atoi: 309 * 310 * This function converts an ascii string into an integer. 311 * 312 * input : string 313 * output : a number 314 */ 315 316int 317atoi(const char *cp) 318{ 319 int number; 320 321 for (number = 0; ('0' <= *cp) && (*cp <= '9'); cp++) 322 number = (number * 10) + (*cp - '0'); 323 324 return( number ); 325} 326 327/* 328 * convert an ASCII string (decimal radix) to an integer 329 * inputs: 330 * p string pointer. 331 * t char **, return a pointer to the cahr which terminates the 332 * numeric string. 333 * returns: 334 * integer value of the numeric string. 335 * side effect: 336 * pointer to terminating char. 337 */ 338 339int 340atoi_term( 341 char *p, /* IN */ 342 char **t) /* OUT */ 343{ 344 int n; 345 int f; 346 347 n = 0; 348 f = 0; 349 for(;;p++) { 350 switch(*p) { 351 case ' ': 352 case '\t': 353 continue; 354 case '-': 355 f++; 356 case '+': 357 p++; 358 } 359 break; 360 } 361 while(*p >= '0' && *p <= '9') 362 n = n*10 + *p++ - '0'; 363 364 /* return pointer to terminating character */ 365 if ( t ) 366 *t = p; 367 368 return(f? -n: n); 369} 370 371/* 372 * Does the same thing as strlen, except only looks up 373 * to max chars inside the buffer. 374 * Taken from archive/kern-stuff/sbf_machine.c in 375 * seatbelt. 376 * inputs: 377 * s string whose length is to be measured 378 * max maximum length of string to search for null 379 * outputs: 380 * length of s or max; whichever is smaller 381 */ 382 383// ARM implementation in ../arm/strnlen.s 384// ARM64 implementation in ../arm64/strnlen.s 385size_t 386strnlen(const char *s, size_t max) { 387 const char *es = s + max, *p = s; 388 while(*p && p != es) 389 p++; 390 391 return p - s; 392} 393 394/* 395 * convert an integer to an ASCII string. 396 * inputs: 397 * num integer to be converted 398 * str string pointer. 399 * 400 * outputs: 401 * pointer to string start. 402 */ 403 404char * 405itoa( 406 int num, 407 char *str) 408{ 409 char digits[11]; 410 char *dp; 411 char *cp = str; 412 413 if (num == 0) { 414 *cp++ = '0'; 415 } 416 else { 417 dp = digits; 418 while (num) { 419 *dp++ = '0' + num % 10; 420 num /= 10; 421 } 422 while (dp != digits) { 423 *cp++ = *--dp; 424 } 425 } 426 *cp++ = '\0'; 427 428 return str; 429} 430 431/* 432 * Deprecation Warning: 433 * strcat() is being deprecated. Please use strlcat() instead. 434 */ 435char * 436strcat( 437 char *dest, 438 const char *src) 439{ 440 char *old = dest; 441 442 while (*dest) 443 ++dest; 444 while ((*dest++ = *src++)) 445 ; 446 return (old); 447} 448 449/* 450 * Appends src to string dst of size siz (unlike strncat, siz is the 451 * full size of dst, not space left). At most siz-1 characters 452 * will be copied. Always NUL terminates (unless siz <= strlen(dst)). 453 * Returns strlen(src) + MIN(siz, strlen(initial dst)). 454 * If retval >= siz, truncation occurred. 455 */ 456size_t 457strlcat(char *dst, const char *src, size_t siz) 458{ 459 char *d = dst; 460 const char *s = src; 461 size_t n = siz; 462 size_t dlen; 463 464 /* Find the end of dst and adjust bytes left but don't go past end */ 465 while (n-- != 0 && *d != '\0') 466 d++; 467 dlen = d - dst; 468 n = siz - dlen; 469 470 if (n == 0) 471 return(dlen + strlen(s)); 472 while (*s != '\0') { 473 if (n != 1) { 474 *d++ = *s; 475 n--; 476 } 477 s++; 478 } 479 *d = '\0'; 480 481 return(dlen + (s - src)); /* count does not include NUL */ 482} 483 484/* 485 * Copy src to string dst of size siz. At most siz-1 characters 486 * will be copied. Always NUL terminates (unless siz == 0). 487 * Returns strlen(src); if retval >= siz, truncation occurred. 488 */ 489 490// ARM and ARM64 implementation in ../arm/strlcpy.c 491size_t 492strlcpy(char *dst, const char *src, size_t siz) 493{ 494 char *d = dst; 495 const char *s = src; 496 size_t n = siz; 497 498 /* Copy as many bytes as will fit */ 499 if (n != 0 && --n != 0) { 500 do { 501 if ((*d++ = *s++) == 0) 502 break; 503 } while (--n != 0); 504 } 505 506 /* Not enough room in dst, add NUL and traverse rest of src */ 507 if (n == 0) { 508 if (siz != 0) 509 *d = '\0'; /* NUL-terminate dst */ 510 while (*s++) 511 ; 512 } 513 514 return(s - src - 1); /* count does not include NUL */ 515} 516 517/* 518 * STRDUP 519 * 520 * Description: The STRDUP function allocates sufficient memory for a copy 521 * of the string "string", does the copy, and returns a pointer 522 * it. The pointer may subsequently be used as an argument to 523 * the macro FREE(). 524 * 525 * Parameters: string String to be duplicated 526 * type type of memory to be allocated (normally 527 * M_TEMP) 528 * 529 * Returns: char * A pointer to the newly allocated string with 530 * duplicated contents in it. 531 * 532 * NULL If MALLOC() fails. 533 * 534 * Note: This function can *not* be called from interrupt context as 535 * it calls MALLOC with M_WAITOK. In fact, you really 536 * shouldn't be doing string manipulation in interrupt context 537 * ever. 538 * 539 * This function name violates the kernel style(9) guide 540 * by being all caps. This was done on purpose to emphasize 541 * one should use FREE() with the allocated buffer. 542 * 543 */ 544char * 545STRDUP(const char *string, int type) 546{ 547 size_t len; 548 char *copy; 549 550 len = strlen(string) + 1; 551 MALLOC(copy, char *, len, type, M_WAITOK); 552 if (copy == NULL) 553 return (NULL); 554 bcopy(string, copy, len); 555 return (copy); 556} 557 558/* 559 * Return TRUE(1) if string 2 is a prefix of string 1. 560 */ 561int 562strprefix(register const char *s1, register const char *s2) 563{ 564 register int c; 565 566 while ((c = *s2++) != '\0') { 567 if (c != *s1++) 568 return (0); 569 } 570 return (1); 571} 572 573char * 574strnstr(char *s, const char *find, size_t slen) 575{ 576 char c, sc; 577 size_t len; 578 579 if ((c = *find++) != '\0') { 580 len = strlen(find); 581 do { 582 do { 583 if ((sc = *s++) == '\0' || slen-- < 1) 584 return (NULL); 585 } while (sc != c); 586 if (len > slen) 587 return (NULL); 588 } while (strncmp(s, find, len) != 0); 589 s--; 590 } 591 return (s); 592} 593 594