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