diff --git a/libc/include/sys/_errdefs.h b/libc/include/sys/_errdefs.h index e27ab7ae7..51d921ba0 100644 --- a/libc/include/sys/_errdefs.h +++ b/libc/include/sys/_errdefs.h @@ -36,6 +36,7 @@ #ifndef __BIONIC_ERRDEF #error "__BIONIC_ERRDEF must be defined before including this file" #endif +__BIONIC_ERRDEF( 0 , 0, "Success" ) __BIONIC_ERRDEF( EPERM , 1, "Operation not permitted" ) __BIONIC_ERRDEF( ENOENT , 2, "No such file or directory" ) __BIONIC_ERRDEF( ESRCH , 3, "No such process" ) diff --git a/libc/inet/inet_pton.c b/libc/inet/inet_pton.c index 4caf9812b..6e74e6af0 100644 --- a/libc/inet/inet_pton.c +++ b/libc/inet/inet_pton.c @@ -1,36 +1,64 @@ -/* $OpenBSD: inet_pton.c,v 1.7 2006/12/30 23:37:37 itojun Exp $ */ +/* $NetBSD: inet_pton.c,v 1.6.10.1 2011/01/10 00:42:17 riz Exp $ */ -/* Copyright (c) 1996 by Internet Software Consortium. +/* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1996,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static const char rcsid[] = "Id: inet_pton.c,v 1.5 2005/07/28 06:51:47 marka Exp"; +#else +__RCSID("$NetBSD: inet_pton.c,v 1.6.10.1 2011/01/10 00:42:17 riz Exp $"); +#endif +#endif /* LIBC_SCCS and not lint */ + +// BEGIN android-added +#define _DIAGASSERT(exp) assert(exp) +#include "../private/arpa_nameser.h" +// END android-added + +// android-removed: #include "port_before.h" + +// android-removed: #include "namespace.h" #include #include #include #include #include -#include "arpa_nameser.h" +#include #include +#include +#include #include -/* +// android-removed: #include "port_after.h" + +// BEGIN android-removed +// #ifdef __weak_alias +// __weak_alias(inet_pton,_inet_pton) +// #endif +// END android-removed + +/*% * WARNING: Don't even consider trying to compile this on a system where * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ -static int inet_pton4(const char *src, u_char *dst); +static int inet_pton4(const char *src, u_char *dst, int pton); static int inet_pton6(const char *src, u_char *dst); /* int @@ -47,9 +75,13 @@ static int inet_pton6(const char *src, u_char *dst); int inet_pton(int af, const char *src, void *dst) { + + _DIAGASSERT(src != NULL); + _DIAGASSERT(dst != NULL); + switch (af) { case AF_INET: - return (inet_pton4(src, dst)); + return (inet_pton4(src, dst, 1)); case AF_INET6: return (inet_pton6(src, dst)); default: @@ -60,51 +92,123 @@ inet_pton(int af, const char *src, void *dst) } /* int - * inet_pton4(src, dst) - * like inet_aton() but without all the hexadecimal and shorthand. + * inet_pton4(src, dst, pton) + * when last arg is 0: inet_aton(). with hexadecimal, octal and shorthand. + * when last arg is 1: inet_pton(). decimal dotted-quad only. * return: - * 1 if `src' is a valid dotted quad, else 0. + * 1 if `src' is a valid input, else 0. * notice: * does not touch `dst' unless it's returning 1. * author: * Paul Vixie, 1996. */ static int -inet_pton4(const char *src, u_char *dst) +inet_pton4(const char *src, u_char *dst, int pton) { - static const char digits[] = "0123456789"; - int saw_digit, octets, ch; - u_char tmp[INADDRSZ], *tp; + u_int32_t val; + u_int digit, base; + int n; + unsigned char c; + u_int parts[4]; + register u_int *pp = parts; - saw_digit = 0; - octets = 0; - *(tp = tmp) = 0; - while ((ch = *src++) != '\0') { - const char *pch; + _DIAGASSERT(src != NULL); + _DIAGASSERT(dst != NULL); - if ((pch = strchr(digits, ch)) != NULL) { - u_int new = *tp * 10 + (pch - digits); - - if (new > 255) - return (0); - if (! saw_digit) { - if (++octets > 4) - return (0); - saw_digit = 1; - } - *tp = new; - } else if (ch == '.' && saw_digit) { - if (octets == 4) - return (0); - *++tp = 0; - saw_digit = 0; - } else + c = *src; + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, isdigit=decimal. + */ + if (!isdigit(c)) return (0); + val = 0; base = 10; + if (c == '0') { + c = *++src; + if (c == 'x' || c == 'X') + base = 16, c = *++src; + else if (isdigit(c) && c != '9') + base = 8; + } + /* inet_pton() takes decimal only */ + if (pton && base != 10) + return (0); + for (;;) { + if (isdigit(c)) { + digit = c - '0'; + if (digit >= base) + break; + val = (val * base) + digit; + c = *++src; + } else if (base == 16 && isxdigit(c)) { + digit = c + 10 - (islower(c) ? 'a' : 'A'); + if (digit >= 16) + break; + val = (val << 4) | digit; + c = *++src; + } else + break; + } + if (c == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + * a (with a treated as 32 bits) + */ + if (pp >= parts + 3) + return (0); + *pp++ = val; + c = *++src; + } else + break; } - if (octets < 4) + /* + * Check for trailing characters. + */ + if (c != '\0' && !isspace(c)) return (0); + /* + * Concoct the address according to + * the number of parts specified. + */ + n = pp - parts + 1; + /* inet_pton() takes dotted-quad only. it does not take shorthand. */ + if (pton && n != 4) + return (0); + switch (n) { - memcpy(dst, tmp, INADDRSZ); + case 0: + return (0); /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if (parts[0] > 0xff || val > 0xffffff) + return (0); + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if ((parts[0] | parts[1]) > 0xff || val > 0xffff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if ((parts[0] | parts[1] | parts[2] | val) > 0xff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + if (dst) { + val = htonl(val); + memcpy(dst, &val, NS_INADDRSZ); + } return (1); } @@ -126,20 +230,23 @@ inet_pton6(const char *src, u_char *dst) { static const char xdigits_l[] = "0123456789abcdef", xdigits_u[] = "0123456789ABCDEF"; - u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp; + u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; const char *xdigits, *curtok; - int ch, saw_xdigit, count_xdigit; + int ch, seen_xdigits; u_int val; - memset((tp = tmp), '\0', IN6ADDRSZ); - endp = tp + IN6ADDRSZ; + _DIAGASSERT(src != NULL); + _DIAGASSERT(dst != NULL); + + memset((tp = tmp), '\0', NS_IN6ADDRSZ); + endp = tp + NS_IN6ADDRSZ; colonp = NULL; /* Leading :: requires some special handling. */ if (*src == ':') if (*++src != ':') return (0); curtok = src; - saw_xdigit = count_xdigit = 0; + seen_xdigits = 0; val = 0; while ((ch = *src++) != '\0') { const char *pch; @@ -147,46 +254,39 @@ inet_pton6(const char *src, u_char *dst) if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) pch = strchr((xdigits = xdigits_u), ch); if (pch != NULL) { - if (count_xdigit >= 4) - return (0); val <<= 4; val |= (pch - xdigits); - if (val > 0xffff) + if (++seen_xdigits > 4) return (0); - saw_xdigit = 1; - count_xdigit++; continue; } if (ch == ':') { curtok = src; - if (!saw_xdigit) { + if (!seen_xdigits) { if (colonp) return (0); colonp = tp; continue; - } else if (*src == '\0') { + } else if (*src == '\0') return (0); - } - if (tp + INT16SZ > endp) + if (tp + NS_INT16SZ > endp) return (0); *tp++ = (u_char) (val >> 8) & 0xff; *tp++ = (u_char) val & 0xff; - saw_xdigit = 0; - count_xdigit = 0; + seen_xdigits = 0; val = 0; continue; } - if (ch == '.' && ((tp + INADDRSZ) <= endp) && - inet_pton4(curtok, tp) > 0) { - tp += INADDRSZ; - saw_xdigit = 0; - count_xdigit = 0; - break; /* '\0' was seen by inet_pton4(). */ + if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && + inet_pton4(curtok, tp, 1) > 0) { + tp += NS_INADDRSZ; + seen_xdigits = 0; + break; /*%< '\\0' was seen by inet_pton4(). */ } return (0); } - if (saw_xdigit) { - if (tp + INT16SZ > endp) + if (seen_xdigits) { + if (tp + NS_INT16SZ > endp) return (0); *tp++ = (u_char) (val >> 8) & 0xff; *tp++ = (u_char) val & 0xff; @@ -199,6 +299,8 @@ inet_pton6(const char *src, u_char *dst) const int n = tp - colonp; int i; + if (tp == endp) + return (0); for (i = 1; i <= n; i++) { endp[- i] = colonp[n - i]; colonp[n - i] = 0; @@ -207,6 +309,8 @@ inet_pton6(const char *src, u_char *dst) } if (tp != endp) return (0); - memcpy(dst, tmp, IN6ADDRSZ); + memcpy(dst, tmp, NS_IN6ADDRSZ); return (1); } + +/*! \file */ diff --git a/libc/string/strerror_r.c b/libc/string/strerror_r.c index f43d417bd..2f26f173c 100644 --- a/libc/string/strerror_r.c +++ b/libc/string/strerror_r.c @@ -21,7 +21,7 @@ __code_string_lookup( const CodeString* strings, for (;;) { - if (strings[nn].code == 0) + if (strings[nn].msg == NULL) break; if (strings[nn].code == code)