1 /* $NetBSD: compat.c,v 1.1.1.4 2015/07/08 15:38:06 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 2003 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* 21 * Copyright (c) 1990, 1993 22 * The Regents of the University of California. All rights reserved. 23 * 24 * Redistribution and use in source and binary forms, with or without 25 * modification, are permitted provided that the following conditions 26 * are met: 27 * 1. Redistributions of source code must retain the above copyright 28 * notice, this list of conditions and the following disclaimer. 29 * 2. Redistributions in binary form must reproduce the above copyright 30 * notice, this list of conditions and the following disclaimer in the 31 * documentation and/or other materials provided with the distribution. 32 * 3. Neither the name of the University nor the names of its contributors 33 * may be used to endorse or promote products derived from this software 34 * without specific prior written permission. 35 * 36 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 37 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 39 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 40 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 41 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 42 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 44 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 45 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 46 * SUCH DAMAGE. 47 */ 48 49 /*! \file */ 50 #if defined(LIBC_SCCS) && !defined(lint) 51 static char sccsid[] = "@(#)strtoul.c 8.1 (Berkeley) 6/4/93"; 52 #endif /* LIBC_SCCS and not lint */ 53 54 #include <config.h> 55 56 #include <limits.h> 57 #include <ctype.h> 58 #include <errno.h> 59 60 #include <lwres/stdlib.h> 61 #include <lwres/string.h> 62 63 #define DE_CONST(konst, var) \ 64 do { \ 65 union { const void *k; void *v; } _u; \ 66 _u.k = konst; \ 67 var = _u.v; \ 68 } while (0) 69 70 /*! 71 * Convert a string to an unsigned long integer. 72 * 73 * Ignores `locale' stuff. Assumes that the upper and lower case 74 * alphabets and digits are each contiguous. 75 */ 76 unsigned long 77 lwres_strtoul(const char *nptr, char **endptr, int base) { 78 const char *s = nptr; 79 unsigned long acc; 80 unsigned char c; 81 unsigned long cutoff; 82 int neg = 0, any, cutlim; 83 84 /* 85 * See strtol for comments as to the logic used. 86 */ 87 do { 88 c = *s++; 89 } while (isspace(c)); 90 if (c == '-') { 91 neg = 1; 92 c = *s++; 93 } else if (c == '+') 94 c = *s++; 95 if ((base == 0 || base == 16) && 96 c == '0' && (*s == 'x' || *s == 'X')) { 97 c = s[1]; 98 s += 2; 99 base = 16; 100 } 101 if (base == 0) 102 base = c == '0' ? 8 : 10; 103 cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; 104 cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; 105 for (acc = 0, any = 0;; c = *s++) { 106 if (!isascii(c)) 107 break; 108 if (isdigit(c)) 109 c -= '0'; 110 else if (isalpha(c)) 111 c -= isupper(c) ? 'A' - 10 : 'a' - 10; 112 else 113 break; 114 if (c >= base) 115 break; 116 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) 117 any = -1; 118 else { 119 any = 1; 120 acc *= base; 121 acc += c; 122 } 123 } 124 if (any < 0) { 125 acc = ULONG_MAX; 126 errno = ERANGE; 127 } else if (neg) 128 /* XXX: acc was declared unsigned! */ 129 acc = -acc; 130 if (endptr != 0) 131 DE_CONST(any ? s - 1 : nptr, *endptr); 132 return (acc); 133 } 134 135 size_t 136 lwres_strlcpy(char *dst, const char *src, size_t size) { 137 char *d = dst; 138 const char *s = src; 139 size_t n = size; 140 141 /* Copy as many bytes as will fit */ 142 if (n != 0U && --n != 0U) { 143 do { 144 if ((*d++ = *s++) == 0) 145 break; 146 } while (--n != 0U); 147 } 148 149 /* Not enough room in dst, add NUL and traverse rest of src */ 150 if (n == 0U) { 151 if (size != 0U) 152 *d = '\0'; /* NUL-terminate dst */ 153 while (*s++) 154 ; 155 } 156 157 return(s - src - 1); /* count does not include NUL */ 158 } 159