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 191int 192strncmp( 193 const char *s1, 194 const char *s2, 195 size_t n) 196{ 197 unsigned int a, b; 198 199 while (n != 0) { 200 a = *s1++; 201 b = *s2++; 202 if (a != b) 203 return a-b; /* includes case when 204 'a' is zero and 'b' is not zero 205 or vice versa */ 206 if (a == '\0') 207 return 0; /* both are zero */ 208 n--; 209 } 210 211 return 0; 212} 213 214 215// 216// Lame implementation just for use by strcasecmp/strncasecmp 217// 218static int 219tolower(unsigned char ch) 220{ 221 if (ch >= 'A' && ch <= 'Z') 222 ch = 'a' + (ch - 'A'); 223 224 return ch; 225} 226 227int 228strcasecmp(const char *s1, const char *s2) 229{ 230 const unsigned char *us1 = (const u_char *)s1, 231 *us2 = (const u_char *)s2; 232 233 while (tolower(*us1) == tolower(*us2++)) 234 if (*us1++ == '\0') 235 return (0); 236 return (tolower(*us1) - tolower(*--us2)); 237} 238 239int 240strncasecmp(const char *s1, const char *s2, size_t n) 241{ 242 if (n != 0) { 243 const unsigned char *us1 = (const u_char *)s1, 244 *us2 = (const u_char *)s2; 245 246 do { 247 if (tolower(*us1) != tolower(*us2++)) 248 return (tolower(*us1) - tolower(*--us2)); 249 if (*us1++ == '\0') 250 break; 251 } while (--n != 0); 252 } 253 return (0); 254} 255 256 257/* 258 * Abstract: 259 * strcpy copies the contents of the string "from" including 260 * the null terminator to the string "to". A pointer to "to" 261 * is returned. 262 * Deprecation Warning: 263 * strcpy() is being deprecated. Please use strlcpy() instead. 264 */ 265char * 266strcpy( 267 char *to, 268 const char *from) 269{ 270 char *ret = to; 271 272 while ((*to++ = *from++) != '\0') 273 continue; 274 275 return ret; 276} 277 278/* 279 * Abstract: 280 * strncpy copies "count" characters from the "from" string to 281 * the "to" string. If "from" contains less than "count" characters 282 * "to" will be padded with null characters until exactly "count" 283 * characters have been written. The return value is a pointer 284 * to the "to" string. 285 */ 286 287// ARM implementation in ../arm/strncpy.c 288char * 289strncpy( 290 char *s1, 291 const char *s2, 292 size_t n) 293{ 294 char *os1 = s1; 295 unsigned long i; 296 297 for (i = 0; i < n;) 298 if ((*s1++ = *s2++) == '\0') 299 for (i++; i < n; i++) 300 *s1++ = '\0'; 301 else 302 i++; 303 return (os1); 304} 305 306/* 307 * atoi: 308 * 309 * This function converts an ascii string into an integer. 310 * 311 * input : string 312 * output : a number 313 */ 314 315int 316atoi(const char *cp) 317{ 318 int number; 319 320 for (number = 0; ('0' <= *cp) && (*cp <= '9'); cp++) 321 number = (number * 10) + (*cp - '0'); 322 323 return( number ); 324} 325 326/* 327 * convert an ASCII string (decimal radix) to an integer 328 * inputs: 329 * p string pointer. 330 * t char **, return a pointer to the cahr which terminates the 331 * numeric string. 332 * returns: 333 * integer value of the numeric string. 334 * side effect: 335 * pointer to terminating char. 336 */ 337 338int 339atoi_term( 340 char *p, /* IN */ 341 char **t) /* OUT */ 342{ 343 int n; 344 int f; 345 346 n = 0; 347 f = 0; 348 for(;;p++) { 349 switch(*p) { 350 case ' ': 351 case '\t': 352 continue; 353 case '-': 354 f++; 355 case '+': 356 p++; 357 } 358 break; 359 } 360 while(*p >= '0' && *p <= '9') 361 n = n*10 + *p++ - '0'; 362 363 /* return pointer to terminating character */ 364 if ( t ) 365 *t = p; 366 367 return(f? -n: n); 368} 369 370/* 371 * Does the same thing as strlen, except only looks up 372 * to max chars inside the buffer. 373 * Taken from archive/kern-stuff/sbf_machine.c in 374 * seatbelt. 375 * inputs: 376 * s string whose length is to be measured 377 * max maximum length of string to search for null 378 * outputs: 379 * length of s or max; whichever is smaller 380 */ 381 382// ARM implementation in ../arm/strnlen.s 383size_t 384strnlen(const char *s, size_t max) { 385 const char *es = s + max, *p = s; 386 while(*p && p != es) 387 p++; 388 389 return p - s; 390} 391 392/* 393 * convert an integer to an ASCII string. 394 * inputs: 395 * num integer to be converted 396 * str string pointer. 397 * 398 * outputs: 399 * pointer to string start. 400 */ 401 402char * 403itoa( 404 int num, 405 char *str) 406{ 407 char digits[11]; 408 char *dp; 409 char *cp = str; 410 411 if (num == 0) { 412 *cp++ = '0'; 413 } 414 else { 415 dp = digits; 416 while (num) { 417 *dp++ = '0' + num % 10; 418 num /= 10; 419 } 420 while (dp != digits) { 421 *cp++ = *--dp; 422 } 423 } 424 *cp++ = '\0'; 425 426 return str; 427} 428 429/* 430 * Deprecation Warning: 431 * strcat() is being deprecated. Please use strlcat() instead. 432 */ 433char * 434strcat( 435 char *dest, 436 const char *src) 437{ 438 char *old = dest; 439 440 while (*dest) 441 ++dest; 442 while ((*dest++ = *src++)) 443 ; 444 return (old); 445} 446 447/* 448 * Appends src to string dst of size siz (unlike strncat, siz is the 449 * full size of dst, not space left). At most siz-1 characters 450 * will be copied. Always NUL terminates (unless siz <= strlen(dst)). 451 * Returns strlen(src) + MIN(siz, strlen(initial dst)). 452 * If retval >= siz, truncation occurred. 453 */ 454size_t 455strlcat(char *dst, const char *src, size_t siz) 456{ 457 char *d = dst; 458 const char *s = src; 459 size_t n = siz; 460 size_t dlen; 461 462 /* Find the end of dst and adjust bytes left but don't go past end */ 463 while (n-- != 0 && *d != '\0') 464 d++; 465 dlen = d - dst; 466 n = siz - dlen; 467 468 if (n == 0) 469 return(dlen + strlen(s)); 470 while (*s != '\0') { 471 if (n != 1) { 472 *d++ = *s; 473 n--; 474 } 475 s++; 476 } 477 *d = '\0'; 478 479 return(dlen + (s - src)); /* count does not include NUL */ 480} 481 482/* 483 * Copy src to string dst of size siz. At most siz-1 characters 484 * will be copied. Always NUL terminates (unless siz == 0). 485 * Returns strlen(src); if retval >= siz, truncation occurred. 486 */ 487 488// ARM implementation in ../arm/strlcpy.c 489size_t 490strlcpy(char *dst, const char *src, size_t siz) 491{ 492 char *d = dst; 493 const char *s = src; 494 size_t n = siz; 495 496 /* Copy as many bytes as will fit */ 497 if (n != 0 && --n != 0) { 498 do { 499 if ((*d++ = *s++) == 0) 500 break; 501 } while (--n != 0); 502 } 503 504 /* Not enough room in dst, add NUL and traverse rest of src */ 505 if (n == 0) { 506 if (siz != 0) 507 *d = '\0'; /* NUL-terminate dst */ 508 while (*s++) 509 ; 510 } 511 512 return(s - src - 1); /* count does not include NUL */ 513} 514 515/* 516 * STRDUP 517 * 518 * Description: The STRDUP function allocates sufficient memory for a copy 519 * of the string "string", does the copy, and returns a pointer 520 * it. The pointer may subsequently be used as an argument to 521 * the macro FREE(). 522 * 523 * Parameters: string String to be duplicated 524 * type type of memory to be allocated (normally 525 * M_TEMP) 526 * 527 * Returns: char * A pointer to the newly allocated string with 528 * duplicated contents in it. 529 * 530 * NULL If MALLOC() fails. 531 * 532 * Note: This function can *not* be called from interrupt context as 533 * it calls MALLOC with M_WAITOK. In fact, you really 534 * shouldn't be doing string manipulation in interrupt context 535 * ever. 536 * 537 * This function name violates the kernel style(9) guide 538 * by being all caps. This was done on purpose to emphasize 539 * one should use FREE() with the allocated buffer. 540 * 541 */ 542char * 543STRDUP(const char *string, int type) 544{ 545 size_t len; 546 char *copy; 547 548 len = strlen(string) + 1; 549 MALLOC(copy, char *, len, type, M_WAITOK); 550 if (copy == NULL) 551 return (NULL); 552 bcopy(string, copy, len); 553 return (copy); 554} 555 556/* 557 * Return TRUE(1) if string 2 is a prefix of string 1. 558 */ 559int 560strprefix(register const char *s1, register const char *s2) 561{ 562 register int c; 563 564 while ((c = *s2++) != '\0') { 565 if (c != *s1++) 566 return (0); 567 } 568 return (1); 569} 570 571char * 572strnstr(char *s, const char *find, size_t slen) 573{ 574 char c, sc; 575 size_t len; 576 577 if ((c = *find++) != '\0') { 578 len = strlen(find); 579 do { 580 do { 581 if ((sc = *s++) == '\0' || slen-- < 1) 582 return (NULL); 583 } while (sc != c); 584 if (len > slen) 585 return (NULL); 586 } while (strncmp(s, find, len) != 0); 587 s--; 588 } 589 return (s); 590} 591 592